具有2m2m关系的数据库设计

时间:2021-02-08 14:38:31

I'd like some advice on how to further develop my models and tables.

我想要一些关于如何进一步开发我的模型和表格的建议。

This model currently allows me to save option that links to disease and state in a m2m relationship. How would I further build this out if I wanted to save outcome and it's associated value that links to state, disease, AND option?

这个模型目前允许我保存连接到m2m关系中的疾病和状态的选项。如果我想保存结果,并且它与状态、疾病和选项相关联的值,我该如何进一步构建它呢?

For example, outcome will have specific options associated to it. Options will a specific state which will have a specific disease linked to it. For every outcome linked to specific options, there will be a value assigned to it.

例如,结果将具有与之相关的特定选项。选项将是一个特定的状态,它将有一个特定的疾病与之相关。对于每个与特定选项相关联的结果,都会有一个赋值给它。

I think I need an intermediate table because of the outcome value the user will assign to it. I'm confused as how to link outcome to option,since option is m2m.

我想我需要一个中间表,因为用户会给它分配结果值。我很困惑如何把结果和选项联系起来,因为选项是m2m。

class Option(models.Model):
    disease = models.ForeignKey(Disease)
    option = models.CharField(max_length=300)

class Outcome(models.Model):      
   disease = models.ForeignKey(Disease)
   outcome = models.CharField(max_length=200)

class DiseaseState(models.Model):
   state = models.CharField(max_length=300)
   disease = models.ForeignKey(Disease)
   option = models.ManyToManyField(Option, blank=True)
   #outcome = models.ManyToManyField(Outcome, blank=True) #will adding this solve my use case? It does not seem like outcome will link to option.

Update:

更新:

For some clarity: A Disease has a DiseaseState. A DiseaseState has an Option. An Option has Outcomes. Outcome has a value assigned to it. Both Option and Outcomes are lists and the user gets to pick from the list.

某种程度上说,一种疾病有一种疾病。一种疾病有一种选择。一个选择的结果。结果有一个赋值给它。选项和结果都是列表,用户可以从列表中选择。

2 个解决方案

#1


1  

I'm not entirely sure I follow, but you have a few options here.

我不确定我是否完全理解,但你在这里有一些选择。

The first is to manually create the intermediate table between Outcome and DiseaseState

第一种方法是手工创建结果与疾病之间的中间表。

class DiseaseStateOutcome(models.Model):
    unique_together = (('disease_state', 'outcome'),)

    disease_state = models.ForeignKey(DiseaseState)
    outcome = models.ForeignKey(Outcome)

    #option foreign key, or m2m relation to option here

Your other option is, if you just want a single option relating to a DiseaseState/Outcome pair, is to just put a ForeignKey from Outcome to Option.

你的另一种选择是,如果你只是想要一个与疾病/结果对相关的单一选项,那么你只需将一个ForeignKey从结果放到选项中。

class Outcome(models.Model):
    #Your other fields here
    option = models.ForeignKey(Option)

#2


1  

Since I can't see your whole class structure (Disease?, State?) I can't get too specific, but I'll try to talk a little about DB design.

因为我看不到你的整个阶级结构(疾病?,状态?)我不能说得太具体,但我会试着谈谈DB设计。

I have a table that holds people, and I want to know their names, and what kind of car(s) they drive:

我有一张能容纳人的桌子,我想知道他们的名字,他们开的是什么样的车:

tbl_person
id int(11)
name varchar(32)

Now I could put a car column in the person table, but some people drive more than one car. So I'll make a table with cars in it, and connect (or relate) each car with a person.

现在我可以在person表中加入car列,但是有些人会开不止一辆车。所以我要做一张有汽车的桌子,把每辆车和一个人联系起来。

tbl_car
id int(11)
car_name varchar(32)
person_id int(11)

That way each row in the car table would have a person.id. This is a Foreign Key relationship.

这样,车表中的每一行都有一个person.id。这是一种外交关系。

Now the problem with this is that I'm going to have a bunch of columns in my car table that have duplicate data, because there will be lots of Toyotas in there, for example.

现在的问题是,我的车表中有一堆列有重复的数据,因为那里会有很多丰田车。

It would be better if I had every car make in a table, and every person in another with a join table between them.

如果我让每一辆车都在一张桌子上生产,而另一张桌子上的每个人之间都有一张连接桌子,那就更好了。

So I now have tbl_person_car:

现在我有了tbl_person_car:

id int(11)
car_id int(11)
person_id int(11)

Notice that each row in this table contains only two Foreign Keys or FKs. It's really important that this join table contain nothing but the FKs needed to perform the join. Failure to do so would jeopardize the referential integrity of the whole database.

注意,该表中的每一行只包含两个外键或FKs。这个连接表只包含执行连接所需的FKs,这一点非常重要。如果不这样做,将危及整个数据库的引用完整性。

Of course, Django builds this join table for you whenever you employ a ManyToMany field in your model. So you never have to worry about it (which is nice, because one wrong move can ruin everything).

当然,当您在模型中使用许多tomany字段时,Django会为您构建这个连接表。所以你不必担心它(这很好,因为一个错误的举动会毁掉一切)。

OK, sorry if that was too elementary, but I hope it explains that if you think your join table needs more data in it, then you've probably got an issue with your design.

好的,抱歉,如果这太简单了,但是我希望它能解释如果您认为您的连接表需要更多的数据,那么您可能对您的设计产生了问题。

I would suggest really getting comfortable with what your models are doing, and don't worry so much about the DB. When I started with Django, I was thinking from the DB side too much, and it caused a bit of pain.

我建议你对你的模特所做的一切要真正感到满意,不要太担心DB。当我开始使用Django时,我从DB的角度想得太多了,这引起了一点痛苦。

So in your case, ask yourself, "What does a disease have?" You might say "a disease has an outcome." The has a relationship is vital to understand in OO design.

所以在你的情况下,问问你自己,“一种疾病有什么?”你可能会说“疾病有结果”。在面向对象的设计中,关系是至关重要的。

What is it, for example that has an Option? Is it a Disease, Patient, Outcome? Whatever it is, then that is probably the model to which an Outcome belongs.

比如,它有什么选项?它是一种疾病,病人,还是结果?不管它是什么,那可能就是结果所属的模型。

Is this making sense? I hope it helps.

这是理解吗?我希望它有帮助。

#1


1  

I'm not entirely sure I follow, but you have a few options here.

我不确定我是否完全理解,但你在这里有一些选择。

The first is to manually create the intermediate table between Outcome and DiseaseState

第一种方法是手工创建结果与疾病之间的中间表。

class DiseaseStateOutcome(models.Model):
    unique_together = (('disease_state', 'outcome'),)

    disease_state = models.ForeignKey(DiseaseState)
    outcome = models.ForeignKey(Outcome)

    #option foreign key, or m2m relation to option here

Your other option is, if you just want a single option relating to a DiseaseState/Outcome pair, is to just put a ForeignKey from Outcome to Option.

你的另一种选择是,如果你只是想要一个与疾病/结果对相关的单一选项,那么你只需将一个ForeignKey从结果放到选项中。

class Outcome(models.Model):
    #Your other fields here
    option = models.ForeignKey(Option)

#2


1  

Since I can't see your whole class structure (Disease?, State?) I can't get too specific, but I'll try to talk a little about DB design.

因为我看不到你的整个阶级结构(疾病?,状态?)我不能说得太具体,但我会试着谈谈DB设计。

I have a table that holds people, and I want to know their names, and what kind of car(s) they drive:

我有一张能容纳人的桌子,我想知道他们的名字,他们开的是什么样的车:

tbl_person
id int(11)
name varchar(32)

Now I could put a car column in the person table, but some people drive more than one car. So I'll make a table with cars in it, and connect (or relate) each car with a person.

现在我可以在person表中加入car列,但是有些人会开不止一辆车。所以我要做一张有汽车的桌子,把每辆车和一个人联系起来。

tbl_car
id int(11)
car_name varchar(32)
person_id int(11)

That way each row in the car table would have a person.id. This is a Foreign Key relationship.

这样,车表中的每一行都有一个person.id。这是一种外交关系。

Now the problem with this is that I'm going to have a bunch of columns in my car table that have duplicate data, because there will be lots of Toyotas in there, for example.

现在的问题是,我的车表中有一堆列有重复的数据,因为那里会有很多丰田车。

It would be better if I had every car make in a table, and every person in another with a join table between them.

如果我让每一辆车都在一张桌子上生产,而另一张桌子上的每个人之间都有一张连接桌子,那就更好了。

So I now have tbl_person_car:

现在我有了tbl_person_car:

id int(11)
car_id int(11)
person_id int(11)

Notice that each row in this table contains only two Foreign Keys or FKs. It's really important that this join table contain nothing but the FKs needed to perform the join. Failure to do so would jeopardize the referential integrity of the whole database.

注意,该表中的每一行只包含两个外键或FKs。这个连接表只包含执行连接所需的FKs,这一点非常重要。如果不这样做,将危及整个数据库的引用完整性。

Of course, Django builds this join table for you whenever you employ a ManyToMany field in your model. So you never have to worry about it (which is nice, because one wrong move can ruin everything).

当然,当您在模型中使用许多tomany字段时,Django会为您构建这个连接表。所以你不必担心它(这很好,因为一个错误的举动会毁掉一切)。

OK, sorry if that was too elementary, but I hope it explains that if you think your join table needs more data in it, then you've probably got an issue with your design.

好的,抱歉,如果这太简单了,但是我希望它能解释如果您认为您的连接表需要更多的数据,那么您可能对您的设计产生了问题。

I would suggest really getting comfortable with what your models are doing, and don't worry so much about the DB. When I started with Django, I was thinking from the DB side too much, and it caused a bit of pain.

我建议你对你的模特所做的一切要真正感到满意,不要太担心DB。当我开始使用Django时,我从DB的角度想得太多了,这引起了一点痛苦。

So in your case, ask yourself, "What does a disease have?" You might say "a disease has an outcome." The has a relationship is vital to understand in OO design.

所以在你的情况下,问问你自己,“一种疾病有什么?”你可能会说“疾病有结果”。在面向对象的设计中,关系是至关重要的。

What is it, for example that has an Option? Is it a Disease, Patient, Outcome? Whatever it is, then that is probably the model to which an Outcome belongs.

比如,它有什么选项?它是一种疾病,病人,还是结果?不管它是什么,那可能就是结果所属的模型。

Is this making sense? I hope it helps.

这是理解吗?我希望它有帮助。