一对多
一个实体如何与自己之间具有一对多关系的表结构?具体来说,我正在开发一个用于追踪动物繁殖的应用程序。每只动物都有一个ID;它也有一个父亲身份证和一个父亲身份身份证。因此,从父代或者母代到后代都有一对多的可能。我倾向于这样的事情:
ID INT NOT NULL PRIMARY KEY SIRE_ID INT DAME_ID INT
并记录已购买并添加到种畜中的那些动物的空值,并在表中记录其余的ID。
所以:
- 有人可以指出我指向讨论这种关系建模的文章/网页吗?
- ID应该是INT还是某种字符串? INT中的NULL表示该动物在数据库中没有父代,但是可以使用带有特殊标志值的String表示同一事物。
- 是否最好通过两个表来建模?我的意思是为动物准备一张桌子,并单独显示一个单独的亲属关系e。 g .:动物ID INT非空主键亲属ID INT非空主键外键SIRE_ID INT主键外键DAME_ID INT主键外键
对于上述情况,我深表歉意:我的SQL生锈了。我希望它能传达我的想法。
解决方案
好吧,这是一种"正常"的一对多关系,我们建议的方法是解决该问题的经典方法。
请注意,两个表是非规范化的(我无法确切指出我应该忘记的超级键不是其他键fsck-I子集的子集的位置,但是我很确定在某处);直观的原因是,第一个中的元组最多匹配第二个中的元组,因此,除非我们有很多动物的父亲和父亲ID为空,否则它在任何情况下都不是一个好的解决方案(它会使性能变差-需要a加入-并且不会降低存储要求)。
INT是ID列的更好选择,如果我们应使用序列生成唯一ID,则更适合使用INT。
将设计分为两张表格没有任何好处。
几个月前,我在MySQL网站上问了类似的问题。我建议我们看看我从Peter Brawley收到的有关这种类型关系的回复:http://forums.mysql.com/read.php?135,187196,187196#msg-187196
如果我们想进一步研究该主题,那么我建议我们研究Wikipedia上的Tree Hierarchies。
另一种建议的体系结构(将被完全规范化)将类似于以下内容:
表:动物
ID |姓名|品种
表格:血统书
animal_id | parent_id | parentType(父亲或者母亲)
将" connect by"子句与SQL一起使用以告诉它要遵循的层次结构。
除非动物可以有很多父母,否则这并不是一对多的关系。
我会将其保留为一张表格,其中包含该动物的唯一键ID,每个父母的一个int字段,以及可能是一个文本字段,用于有关该动物的一般注释,例如在这种情况下的购买位置。
我认为,既然很明显一只动物只有一个父亲和一个水坝,那么使用一张桌子是最有意义的。我的首选是使用int或者bigint作为行标识符,其null值表示没有关系。然后,我可能会使用其他方法来唯一标识动物,这样它们就不会出现在表中两次,也不会在该列上创建唯一索引。
我认为我们仅使用一张桌子的布局就可以了。我们绝对希望将SIRE_ID和DAME_ID保留为与ID相同的数据类型。我们还希望将它们声明为FOREIGN KEY(可以将外键指向回到同一表,并且外键也可以为null)。
ID INT NOT NULL PRIMARY KEY SIRE_ID INT REFERENCES TABLENAME (ID) DAME_ID INT REFERENCES TABLENAME (ID)
使用此布局,我们可以轻松地查找父动物,也可以为给定的动物构建后代树(对于Oracle,有CONNECT BY)
好像我们想构建一棵树一样。
怎么样呢?:
ID Primary Key, Parent_ID Foreing_Key ( data )
有一些功能可以在与自身相关的表中进行查询。请参阅"连接方式"的语法:http://www.adp-gmbh.ch/ora/sql/connect_by.html
我不了解动物育种,但听起来Sire_ID是父亲,而Dame_ID是母亲?没问题。每只动物一行,对于购买的动物,其sire_和dame_ID为空,我没有发现任何问题。
[ID],[Sire_ID],[Dame_ID]; 0,null,null (male) 1,null,null (female) 2,null,null (female) 3,0,1 (male) 4,0,2 (male) 5,null,null (female) 6,3,5 7,4,5
等等。我们可能会在while循环中填充TreeView或者XmlNodeList ...
While (myAnimal.HasChildren) { Animal[] children = GetChildren(Animal.ID) for (int x=0; x<children.length; x++) myAnimal.Children.Add(children[x]); }
在这种情况下,Animal.Children是动物的集合。因此,myAnimal.Children [0]。父亲将返回myAnimal。 .Parent []可以是其两个父级的集合,只要[0]始终是一个父级(父亲),而[1]始终是另一个父级(母亲),则应该起作用。
将ID设为自动编号PK,并通过返回其父ID来以编程方式分配Sire_ID和Dame_ID。尽管我们确实愿意,但两个父ID都可以引用回ID,因此不需要任何外键关系。