3

我正在为一个程序创建一个数据库,我应该在其中模拟家庭中的一些关系。 例如: X 是 Y 的父亲,Y 是 X 的儿子

所以,我有一个成员表,其中包含有关每个成员的所有信息,所以我考虑在成员表与其自身之间建立多对多关系,以便Member_Member桥表将列“FK_FromID,FK_ToID”作为复合键(是这对吗?)和“FK_RelationType”作为RelationTypes表的外键,其关系类型为“父亲、母亲、儿子、女儿”,两个关系从成员表到这两个外键是一对多的

我的问题是:删除时如果我选择级联,那么我会循环,因为如果我删除一个成员,那么Member_Member桥中的相关记录会有两个删除传递,知道在程序中每当我插入父关系时,我都会插入一个子关系以及 Member_Member 表中的关系,是否有一种方法或解决方法可以启用级联,以便每当我删除一个成员时,我都会删除Member_member中的相关记录,无论记录在外键列中还是外键列中

所以,我不知道该怎么做,这是一个正确的设计还是什么?,我应该怎么做自行车,还有你认为对于同样的问题更好的设计应该是知道我需要指定两方之间什么样的关系

非常感谢您的帮助,对于糟糕的英语 Bishoy 感到抱歉

4

2 回答 2

2

SQL 不能很好地处理这样的“网络”问题。

成员-成员桥表是一个糟糕的名字。这是一个“成员-父母”(或“父母-孩子”)的桥梁。桥接表不应有“复合键”。桥接表有一个代理键(只是一个序号)和一对对其他表的 FK 引用。这两个 FK 应该具有像“member”和“parent”这样的名称,以便完全清楚地说明此表中的关系。

每个人都有父母。不是每个人都有孩子。有些父母在这个数据库中没有父母;他们是“顶级父母”。

如果顶级父级在父子桥中具有父 FK 为 NULL 的行,这是最简单的。这样你就可以避免超复杂的外连接——每个成员至少有一个成员父行;理想情况下是两个。

由于关系是可传递的,因此您会发现许多“循环”问题。

请注意,您无法在单个标准 SQL 查询中找到所有家庭成员,或所有回到家庭顶部的父母,或所有子孙。有一些 SQL 扩展使这成为可能,但标准并不能很好地处理它。

级联删除效果不佳,因为家庭中的关系以两种方式定向(父对子,子对父),但 SQL 只有一种方向(FK 引用)。

您可以尝试确保每个成员必须在“member-parent”中至少有一个(最多两个)行,并且删除成员会删除“member-parent”中的两行并且键具有正确的名称,你可能会做这项工作的一部分。

请注意,当您删除成员时,这将破坏他们的父关系。您删除了成员父行。那挺好的。他们的孩子呢?其他具有成员父级引用此已删除父级的行现在已损坏。这是什么意思?应该做什么?

没有标准答案。从连通图中删除行会使元素不连通。你必须为此制定一些合理的规则。

由于 SQL 在这方面做得不好,所有的设计似乎都会有问题。

于 2010-03-02T11:12:58.610 回答
0
  1. 假设每个成员只能有一个母亲和一个父亲,您可以通过简单地在表中保留一个mother_idandfather_id字段来导出所有关系。members

    但是,这仅在您的数据库没有丢失信息的情况下才有效。例如,如果成员 X 是成员 Y 的兄弟,则除非 X 和 Y 的父母存储在数据库中,否则无法知道这一点。

    如果您的数据库不会丢失信息,则上述方法可能更容易管理数据完整性。然而,查询可能会变得有点复杂。

  2. 你建议的member_member桥有一个严重的问题,因为它暗示了关系的方向,所以如果 X 是 Y 的父亲,Y 也是 X 的儿子。你建议在两个方向上定义关系两次,但总的来说这不推荐。这是数据复制的一种形式,您可能很难通过数据复制来强制执行参照完整性。请记住,DBMS 不知道 X 是 Y 的父亲与 Y 是 X 的儿子是一样的。

我知道这不是一个完整的答案,而只是一些观察。我完全同意S.Lott 的回答,因为没有标准的方法可以用关系数据库“解决”这个问题。

于 2010-03-02T11:16:57.963 回答