以牺牲 2NF 为代价获得参照完整性 - 这是一个合理的权衡



请考虑以下两个表:

Table A: [K1, K2, PropA] 
Table B: [K3, PropB]

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

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

在我看来,解决方案是在应用程序层强制执行它,或者将K1列传播到表 B,以便它包含表 A 的整个外键。

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

我正在使用MSSQL和Oracle。

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

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

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

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

看到对或你看到错,取决于视角。

真正的解决方案是 DBMS 供应商支持包含依赖项的一般情况,其中外键只是一个特例。

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

一个为您提供解决方案的系统既不涉及"应用程序中的强制"也不涉及"搞砸设计",这是 shark.armchair.mb.ca/~erwin。 披露:该项目是我自己制作的。

[*] 或将所有约束强制代码放在触发器中,以便至少新应用程序不会"忘记"强制实施某些给定的现有业务规则。

最新更新