【问题标题】:Obtain referential integrity at the expense of 2NF- is it a reasonable trade off?以牺牲 2NF 为代价获得参照完整性——这是一个合理的权衡吗?
【发布时间】:2023-03-31 22:06:01
【问题描述】:

考虑以下两个表:

Table A: [K1, K2, PropA] 

Table B: [K3, PropB]

表 A 的主键是复合 [K1,K2]。 表 B 的主键是K3

表对表 B 具有包容性依赖关系-K3 中的值必须与 K2 中的值匹配。不幸的是,由于K2 不是唯一的主键,我无法在这些列上定义外键约束。

在我看来,解决方案是要么在应用层强制执行它,要么将K1 列传播到表 B,这样它将包含表 A 的整个外键。

我的问题:这在数据库设计中被认为是好的还是坏的做法?假设从维护角度或完整性角度来看,添加额外的列不是问题(插入是事务性的)。

我正在使用 MSSQL 和 Oracle。

【问题讨论】:

  • K3 是唯一的吗?你能把Table A -> K2的外键映射到K3吗?我们需要了解有关数据关系的更多细节以帮助您,但您所描述的内容(或我的理解方式)听起来不是好的做法。
  • @Vitaliy 你没有提到你正在使用什么 DBMS。请注意,并非所有 DBMS 都受到此限制。在某些情况下(MySQL 是一个示例),您可以在两个表之间创建引用完整性约束,即使此类约束的目标是非唯一且不可为空的。对于不直接支持此类约束的软件,有可能的解决方法。您的问题确实提出了一个重要的观点:现代数据库软件对数据完整性约束的支持通常很差,这意味着数据库设计人员有时不得不做出一些尴尬的妥协。
  • 如果一个特定的K2 值有多个K1 值,表B 中将使用哪一个?
  • @sqlvogel - MSSQL 和 Oracle。
  • @Damien_The_Unbeliever - K2 在 B 中是独一无二的。

标签: database database-design foreign-keys referential-integrity


【解决方案1】:

创建表 C,只有一个属性 K2,它是主键。现在您可以使用外键约束来引用 K2。

将 K1 属性放入表 B 中可能是个坏主意。如果我理解你正确地这样做,看起来它会创建一个违反 2NF 的非键依赖项。

您的问题确实提出了一个重要的观点:现代数据库软件对数据完整性约束的支持通常很差,这意味着数据库设计人员有时不得不做出一些尴尬的妥协。

【讨论】:

  • 但是问题仍然存在,因为我仍然需要保持 A 和 C 之间的参照完整性。违规确实存在。问题是收益是否大于损失(我认为是,但我正在寻找专家建议)。
  • 您可以在 A 中创建一个引用 C 的外键约束,并在 B 中创建另一个引用 C 的外键约束。完整性在 2 个 RI 约束中而不是 1 个中保持。
  • 我明白了,但我不能使用级联删除..(从表 A 开始,应该传播到 B)。我一开始没有提到这个,但是失去这个很可惜。
  • @sqlvogel:B 可能引用 C 中的值,但不在 A 中。
  • @Mike:“你的问题确实提出了一个重要的观点:现代数据库软件对数据完整性约束的支持通常很差,这意味着数据库设计人员有时不得不做出一些尴尬的妥协。”
【解决方案2】:

"...解决方案是在应用层强制执行或传播..."

看对错,取决于视角。

真正的解决方案是让 DBMS 厂商支持包含依赖的一般情况,其中外键只是一种特殊情况。

但只要 DBMS 供应商不这样做,您就是对的,只要您继续限制自己对这些供应商的产品的提供,您就别无选择,只能将约束实施转移到应用程序 [* ],或者用你需要的所有丑陋的黑客来搞砸设计,以便只使用 FK 来强制执行你的约束。

为您提供既不涉及“在应用程序中执行”也不涉及“搞砸设计”的解决方案的系统位于 Shark.armchair.mb.ca/~erwin。披露:该项目是我自己制作的。

[*] 或将所有约束执行代码放在触发器中,这样至少新应用程序不会“忘记”执行某些给定的现有业务规则。

【讨论】:

    猜你喜欢
    • 2017-03-27
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 2011-04-20
    相关资源
    最近更新 更多