一对多对自己

时间:2008-10-01 21:54:29

标签: database-design data-modeling table-structure

如何为一个可以与自身建立一对多关系的实体构建一个表?具体来说,我正在开发一个跟踪动物繁殖的应用程序。每只动物都有一个ID;它还有一个父亲ID和一个女性ID。所以有可能从父亲或贵妇到其后代中有一对多。我会倾向于这样的事情:

ID INT NOT NULL PRIMARY KEY
SIRE_ID INT 
DAME_ID INT

并记录购买并添加到种畜中的那些动物的空值以及表中其余的ID。

所以:

  1. 有人能指点我吗? 讨论的文章/网页 建模这种关系?
  2. ID应该是INT还是某种类型 串? INT中的NULL会 表明动物没有 数据库中的父项但是一个字符串 可以使用特殊标志值 用来表示同样的事情。
  3. 这可能是最好的建模 通过两张桌子?我的意思是一张桌子 对于动物和一个单独的 表格仅表示亲属关系e。 G:

    动物

    ID INT NOT NOT PRIMARY KEY

    亲属

    ID INT NOT NOT PRIMARY KEY FOREIGN KEY

    SIRE_ID INT PRIMARY KEY FOREIGN KEY

    DAME_ID INT PRIMARY KEY FOREIGN KEY

  4. 我为上述事件道歉:我的SQL生锈了。我希望它能传达我正在思考的东西。

9 个答案:

答案 0 :(得分:6)

嗯,这是一种“正常”的一对多关系,你建议的方法是解决它的经典方法。

请注意,两个表是非规范化的(我不能确切地指出超级密钥不是很好应该是其他密钥fsck-I-forgot部分的子集,但是我'我很确定它在某处);直观的原因是第一个元组中的元组最多匹配第二个元组中的元组,所以除非你有很多具有无效父亲和贵宾ID的动物,否则它在任何前景中都不是一个好的解决方案(它会恶化性能 - 需要加入 - 并且不会降低存储要求。)

答案 1 :(得分:4)

我认为只使用一个表的布局很好。您肯定希望将SIRE_ID和DAME_ID保持在与ID相同的数据类型中。您还希望将它们声明为FOREIGN KEYs(可以将外键指向同一个表,并且外键也可以为null)。

ID INT NOT NULL PRIMARY KEY
SIRE_ID INT REFERENCES TABLENAME (ID)
DAME_ID INT REFERENCES TABLENAME (ID)

使用此布局,您可以轻松查找父动物,还可以为给定动物构建后代树(对于Oracle,有连接方)

答案 2 :(得分:3)

几个月前我在MySQL网站上问了一个类似的问题。我建议您看看我从Peter Brawley收到的有关此类关系的回复: http://forums.mysql.com/read.php?135,187196,187196#msg-187196

如果您想进一步研究该主题,我建议您查看维基百科上的树层次结构。

另一种建议的架构(完全规范化)将如下所示:

表:动物

ID |名称|繁殖

表:血统

animal_id | parent_id | parentType(父亲或女性)

答案 3 :(得分:1)

INT是ID列的最佳选择,如果您应该使用序列生成唯一ID,则更适合。

我认为将设计分成两个表没有任何好处。

答案 4 :(得分:1)

我不知道动物繁殖,但听起来你的Sire_ID是父亲而Dame_ID是母亲?没问题。对于购买的动物,每只动物一行,null 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] .Feather将返回myAnimal。 .Parent []可以是它的两个父母的集合,只要[0]总是一个父(父亲)而[1]总是另一个(母亲),它应该工作。

使ID成为自动编号PK,并通过返回其父项的ID以编程方式分配Sire_ID和Dame_ID。如果你真的想要,两个父ID都可以引用回ID,那么就不需要外键关系。

答案 5 :(得分:0)

将“connect by”子句与SQL一起使用,告诉它要遵循哪个层次结构。

答案 6 :(得分:0)

这不是真正的一对多关系,除非动物可以有很多父母。

我会把它留作一个单独的表,其中包含动物的唯一键ID,每个父母的一个int字段,可能还有一个文本字段用于关于动物的一般注释,如果它是在哪里购买的话案件。

答案 7 :(得分:0)

我认为,因为很明显动物只有一个父亲和一个大坝,所以使用一张桌子最有意义。我的首选是使用int或bigint作为行标识符,空值表示没有关系。那么,我可能会使用其他方法来唯一地识别动物,这样它们就不会在表中结束两次并在该列上创建一个唯一的索引。

答案 8 :(得分:0)

好像你想要建造像树一样的东西。

怎么样?:

 ID          Primary Key,
 Parent_ID   Foreing_Key
 ( data )

在与自身有关系的表中执行查询有一些功能。请参阅连接方式http://www.adp-gmbh.ch/ora/sql/connect_by.html

的语法