【问题标题】:When you do not use foreign keys between tables how else do you then express a relationship当您不在表之间使用外键时,您如何表达关系
【发布时间】:2012-07-10 04:24:48
【问题描述】:

我有 2 张桌子。父子表。当我删除父记录时,他们不应该删除子记录。因此我不使用 ON Delete cascade。而且我也根本不想使用外键,因为如果仍然引用了子记录,我将无法删除父记录。使 FKey 可以为空以具有可选关系也是没有选择的,因为只有当存在相关的父级时才能存在子级。

OK FKey 完全删除。在我的实体关系图中,这两个表之间没有关系。但事实并非如此。当我在 6 个月后查看图表时,这可能会产生误导。

你现在会做什么?

【问题讨论】:

  • This->"当我删除父记录时,他们不应该删除子记录。"似乎与“使 FKey 可以为空以具有可选关系也不是选项相矛盾,因为只有当存在相关父级时,子级才能存在。”一个或另一个可以是真的,但不能两者都是。
  • 嗯.. 应该没有删除关系,但应该有明显可见的 Get-data-relation,比如获取某个父级的所有子级。在那种情况下,我不需要外键。但是如果没有外键,我根本无法在图表中表达关系。

标签: sql foreign-keys parent-child


【解决方案1】:

如果存在子记录,则删除父记录是一种不好的做法。您可能会考虑是否最好使用 is_Active 标志来代替软删除,并通过将记录留在那里以报告历史信息来保持数据完整性。

【讨论】:

  • 我删除了父级,但子级应为报告/观察问题保持“是”。为什么要让子表中的 IsActive 字段变得更好?在没有外键的情况下,6 个月后我仍然看不到这两个表的真实连接。
  • 在父级中处于活动状态。否则,您会丢失父表中的数据(因此您知道客户 12345 于 2011 年 5 月 13 日订购了东西,但无法知道客户 id 12345 是谁)并且必须进行非规范化(并可能通过触发器或不取决于信息的历史性)或进行软删除。例如,假设您删除了一个有订单的客户。他们后来订购的物品因危及生命的问题而被召回。难道你不知道是谁订的吗?
  • 在那种危及生命的情况下,实际上应该禁止删除客户;-)
  • 即使我会通过“停用”已删除的父记录来执行此软删除。我的图表中的关系在哪里可见?
  • 你仍然需要正式创建外键约束
【解决方案2】:

假设您有时想删除父行(而不仅仅是标记它们)而不删除子行,在我看来您有两个选择。

  1. 删除父行时,将子表中的父键设为空。
  2. 删除父行时,将父键保留在子表中。

在第一种情况下,使用外键和ON DELETE SET NULL 来执行此操作。 (假设您的 dbms 支持该约束。)

在第二种情况下,不使用外键约束。

您对不可为空的外键的要求没有意义。一方面,你说只有有相关的父母,孩子才能存在。另一方面,您想删除父级而不删除子级。这两个要求不能很好地结合在一起。

【讨论】:

  • 是的,他们在一起玩得不好,但这是我的要求。具体:1个版本有N个测试计划。当某人愚蠢到删除发布记录时,由于报告/统计等原因,不应该删除此版本的所有测试计划......
  • 好的,我想表达一个关系,我使用 FK 并使其可以为空以防止 FK 约束。我不太喜欢 HLGEM 的 IsActive。不适合我的设计和更多工作;-)
  • 如果删除发布记录是愚蠢的,正确的做法是撤销对该表的删除权限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 2016-03-19
相关资源
最近更新 更多