参照完整性约束能否帮助解决数据冗余问题?
3 回答
参照完整性约束只是“一般数据库约束”的一个子集。
规范化和数据库约束是不同但相互交织的概念。
假设您有一个表 CUSTOMERORDER (custID, custName, orderID),它表示“由#custID# 标识且名为#custName# 的客户已下达由#orderID# 标识的订单”。
由于 FD custID->custName 可能适用,因此该表不太可能在 3NF 中。但是,假设我们仍然保留这种单桌设计。那么我们必须做些什么来强制数据的一致性?我们必须执行上面提到的 FD。我们必须注意,如果同一个客户下第二个订单,那么两行中的 custName 将是相同的。我们必须禁止像 (1, Smith, 2) 和 (1, Jones, 7) 这样的行同时出现在表中。这是一种要强制执行的数据库约束,以使我们的设计符合所有规定的业务规则。
但请注意,我们在这里没有任何“参考”约束。显然,因为没有第二个表可以参考。
另请注意,这种单表设计“自动”实施了一些其他可能不会立即明显的约束。例如,我们的单表设计使得 orderID 不可能在没有相应的 custID 和 custName 的情况下存在。(如果你在考虑空值,就别再这样了。在关系理论中,不存在“空”之类的东西。)“规则”如果注册了一个orderID,那么也必须存在一个对应的custID PLUS custName , 被我们的设计“隐式”强制为单表。
但是现在我们将我们的设计分解为一个包含两个表的设计,正如传统的归一化理论所规定的那样:
CUSTOMER(custID, custName) KEY custID;ORDER(custID, orderID) KEY custID,orderID ;
我们必须执行的业务规则仍然相同,即:(a) 不能有两个客户具有相同的 custID 但名称不同(即我们的 FD),以及 (b) 任何订单都不能没有相应的 custID加上该订单的custName。
让我们看看我们的两表设计如何处理这些业务规则。(a) 显然是通过将 custID 声明为 CUSTOMER 上的键来强制执行的。至于 (b),很明显,如果不记录 custID,就不可能在 ORDER 中记录 orderID。但这足以保证所有 ORDER 行也会有一个相应的custName吗?显然没有。这就是为什么我们需要在 ORDER 和 CUSTOMER 之间引入明显的参照完整性规则。
因此,RI 约束确实“有助于解决数据冗余问题”,从某种意义上说,通过分解表,并在整体设计中引入 RI 约束,它们可以消除某种冗余,同时保持数据完整性的某些保证。如果无法在设计中引入 RI 约束,我们只会以牺牲数据一致性为代价来消除冗余。
Referential integrity guarantees only referential integrity.
It's how you lay out your database that prevents redundancy (see normalization as Oded pointed out).