识别关系 - 多对多

时间:2012-09-12 09:07:17

标签: mysql database database-design database-schema

我为日托中心建立了一个小型数据库。我一直在阅读识别和非识别关系,我仍然对整个事情感到困惑。我一直在使用MySQL Workbench来设计数据库。

现在,父母和孩子的标准是Parent可以有一个或多个Children,反之亦然 - ParentsChildren之间的关系是多对多。解决这个问题的最佳方法(据我所知)是制作第三个表 - Parets_Children并将其用作其他两个表之间的“连接”:

Parents - 1:n - Parents_Children n:1 - Children

现在我遇到的问题是在这里使用识别关系。其逻辑是没有父母就没有孩子可以存在,父母不会成为日托的成员,除非他们在那里至少有一个孩子。它们都不会“孤独”存在。但是,当让MysQL WB为我排序时,它会创建一个非识别关系(我认为) 非常简化的代码:

CREATE TABLE 'parents' (
  'id_parents' SMALLINT UNSIGNED NOT NULL ,
  'name' VARCHAR(48) NOT NULL ,
  PRIMARY KEY ('id_parents');

CREATE TABLE 'parents_children' (
  'id_parents' SMALLINT UNSIGNED NOT NULL ,
  'id_children' SMALLINT UNSIGNED NOT NULL ,
  PRIMARY KEY ('id_parents', 'id_children') ,
  FOREIGN KEY ('id_parents') REFERENCES 'parents' ('id_parents' )
  FOREIGN KEY ('id_children' ) REFERENCES 'children' ('id_children' );

CREATE TABLE 'children' (
  'id_children' SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT ,
  'name' VARCHAR(48) NOT NULL ,
  PRIMARY KEY ('id_children');

此输出是否足以达到所需的功能?我误解了整个关系吗?我希望我的问题不是太难以理解。

3 个答案:

答案 0 :(得分:2)

从您提供的架构中我可以看到外键约束存在于表parents_children上,这将确保父和子之间的链接只有在父和子都存在的情况下才能存在。

但是,这不会阻止您在parents中插入条目,而在parents_children中没有附带条目或children

简而言之,这种模式允许父母存在,没有孩子。

这里的逻辑问题是,在parents_children中创建关系之前需要创建父级和子级(由于外键关系)。但是,您正在寻找的额外逻辑(没有孩子没有父母,反之亦然)需要父母和孩子之间的所有链接才能创建父母或孩子。

你在这里看到了鸡/蛋的问题吗?

答案 1 :(得分:1)

  

逻辑是没有父母和父母,没有孩子可以存在   除非他们至少有一个孩子,否则不会成为日托的成员   那里。

要以一种简单的方式实现这一点..有一个表MyDayCare,您可以在其中添加以下列:RecordID, ChildID, ChildName, ParentID, ParentName
插入记录时,您必须计算下一个ChildIDParentID。 您可以在表格中添加其他库存,例如DateOfBirth,以便唯一标识每个父子对。

删除子项时,父项也会被删除,反之亦然 您甚至可以为同一个孩子(在不同的行中)存储多个父级的记录。通过使用简单的SELF JOIN,您可以获取特定子项或父项所需的任何数据。

请注意,这不是设计数据库表的最佳方式,但根据您的要求,这也可以。

答案 2 :(得分:1)

是否在结点(aka。链接)表Parets_Children上使用标识关系取决于您希望此表具有哪种主键。

正如您已经指出的那样,识别关系将产生“自然”复合PK {id_parents, id_children}。非识别关系将允许您拥有“替代”PK,以及到(现在替代)密钥{id_parents, id_children}

除非您有a specific reason代理密钥,否则在联结表上只有一个自然PK就足够了。

  

逻辑是,没有父母,没有孩子可以存在,父母不会成为日托的成员,除非他们在那里至少有一个孩子。

不幸的是,至少有一个孩子的存在并不容易通过纯粹的声明方式强制执行。实际上(据我所知),不可能在不支持延迟约束的MySQL等DBMS上声明性地强制执行它,这在将父母和孩子插在一起时打破鸡与蛋的问题是必要的。 / p>

如果确实如此(支持递延的FK),每个父母至少有一个孩子的存在可以像这样以声明方式强制执行:

enter image description here

parentparent_child之间的循环依赖引起的鸡与蛋问题将通过推迟FK的强制执行来解决,直到插入所有必要的行为止。

目前,您必须在应用程序代码中执行此操作,或者使存储过程确保正确的行为,然后通过它们仅操作 数据。