2

我为日托中心制作了一个小型数据库。我一直在阅读有关识别和非识别关系的内容,但对整个事情仍然有些困惑。我一直在使用 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');

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

4

3 回答 3

2

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

parents然而,这并不能阻止您在没有附带条目的情况下parents_children插入条目children

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

您的逻辑问题在于,在创建关系之前需要创建父子关系parents_children(由于外键关系)。但是,您正在寻找的附加逻辑(无子无父,反之亦然)将需要父子之间的所有链接,然后才能创建父子或子。

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

于 2012-09-12T09:11:30.767 回答
1

逻辑是,没有父母,任何孩子都无法生存,除非他们在那里至少有一个孩子,否则父母不会成为日托的成员。

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

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

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

于 2012-09-12T09:41:10.873 回答
1

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

{id_parents, id_children}正如您已经指出的,识别关系将产生一个“自然”的复合 PK 。除了(现在是备用的) key之外,非识别关系将允许您拥有一个“代理”PK {id_parents, id_children}

除非您有代理键的特定原因,否则在联结表上只有一个自然 PK 就足够了。

逻辑是,没有父母,任何孩子都无法生存,除非他们在那里至少有一个孩子,否则父母不会成为日托的成员。

不幸的是,至少有一个孩子的存在并不容易通过纯粹的声明方式来强制执行。事实上(至少据我所知)不可能在不支持延迟约束的 DBMS(如 MySQL)上以声明方式强制执行它,这对于在将父子节点插入在一起时打破先有鸡还是先有蛋的问题是必要的。

如果确实如此(支持延迟的 FK),则可以像这样声明性地强制每个父母至少有一个孩子的存在:

在此处输入图像描述

parent由和之间的循环依赖引起的先有鸡还是先有蛋的问题parent_child可以通过推迟执行 FK 直到插入所有必要的行来解决。

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

于 2012-09-12T11:43:32.073 回答