破坏的参照完整性:Edgar Codd会说什么?

时间:2009-03-16 16:20:33

标签: referential-integrity relational-model

我试图理解关系模型的规则,最初由Edgar Codd在1970年定义。

具体而言,我对参照完整性是否是他的关系模型的一部分感兴趣。我将尝试演示以下示例(只是为了使这个问题很漂亮):

客户

+------+------------
| Name | Address
|------+------------
| John | ....
| Mike | ....
| Kate | ....
+------+------------

发票

+------+------------
|  ID  | Customer
|------+------------
|   1  | John
|   2  | John
|   3  | Mary
+------+------------

现在,您可以看到,我们有一张发票,其中客户(外键)是 Mary 。这会违反他的关系模型吗?埃德加·科德会不会看到这个并说,哎呀,到底是什么?或者他会说,这完全没问题......

这是一个理论问题。

6 个答案:

答案 0 :(得分:4)

如果Customers表中没有名为Mary的客户,则表之间没有参照完整性。具体来说,外键是指不存在的主键。

这会打破关系模型吗?不是。它是在关系模型中定义的(即缺乏参照完整性),表明基础数据存在问题。

来自Edgar Codd的“大型共享数据库数据的关系模型”(来自ACM通讯,第13卷,第6期,1970年6月):

  

可能是用户打算插入其他一些内容的情况   元素到P - 插入将变换a的元素   一致状态进入一致状态。关键是系统   没有,通常无法解决这个问题   询问其环境(也许是创建该环境的用户)   不一致)。

因此,假设存在参照完整性问题,并且需要用户或系统通过某种编程方法解决这些问题。

答案 1 :(得分:3)

对于被认为是关系完整的语言(由Codd创造的短语),它必须支持一组关系运算符,称为relational algebra。请注意,没有一个真正的关系代数:Codd提出了第一个代数,但是其他人已经对Codd(例如The Third Manifesto)进行了改进和建立,我相信他会认为这是正确的。

参照完整性不是关系运算符,因此不要求语言的关系完整性。参照完整性约束是否是 DBMS 的有用或必要特征是另一回事。

答案 2 :(得分:2)

我阅读以下内容清楚地说明参照完整性包含在关系模型中:

  

两个完整性规则适用于每个人   关系数据库:

     

1实体完整性:
  没有任何标记   任何属性都允许使用type   这是主要组成部分   基础关系的关键

     

2参考完整性:
  设D为a   域中的一个或多个   单属性主键绘制   他们的价值观设K是外键   从域D中获取其值。   每个未标记的值都出现在   K也必须存在于数据库中   某些主键中的值   基础关系。

Missing information (applicable and inapplicable) in relational databases,”E. F. Codd,ACM SIGMOD Record,vol。 15,不。 4,pp.53-78,1986。

通过“任一类型的标记”,他指的是一个未知值,我们今天使用NULL。本文提出了两种不同类型的未知值,一种是“适用但缺失”,另一种是“不适用”。

通过“未标记”,他意味着不是NULL。


来自@dportas的评论:实际上,你甚至不需要引用的关系是空的来进行论证。它可以包含一些行,但由于K中的A标记不能说等于该引用关系中存在的任何值,因此无法说假设的缺失值满足约束。因此,允许A标记必须成为一种信念行为,一旦提供了一个值,它就会满足约束条件,因为否则该行在插入时就会无效,我们必须支持这个概念。违反追溯约束,这是毫无意义的。

答案 3 :(得分:2)

关系模型不需要将引用完整性功能应用于每个关系数据库 - 如果这些约束不相关或不需要,那将是荒谬的。想想俱乐部会员名单,包括姓名,地址和会员编号。那里的RI约束不一定有任何用处,但如果数据以关系的形式存储,它仍然是关系数据库。

即使是Codd的13条规则也不要求RDBMS必须支持创建RI约束的能力。只是外键非常有用,大多数RDBMS都应该拥有它们。

答案 4 :(得分:1)

首先你要问的是RM的RI部分:

  

参照完整性是否是他的关系模型的一部分

是。来自Codd的经典"你的DBMS真的是关系型的吗?"计算机世界,1985年10月14日:

  然而,重要的是要记住,关系模型包括三个主要部分:结构部分,操纵部分和完整性部分 - 这个事实经常被人们遗忘。

  

规则10:特定关系数据库特有的完整性约束必须在关系数据子语言中定义,并且可以在目录中存储,而不是在应用程序中。

然后你用一个不同而含糊不清的问题来解释:

  

我们有一张发票,其中客户(外键)是玛丽。这会违反他的关系模型吗?

如果您的意思是:RM是否允许违反声明的FK,即DBMS没有停止?

没有。这将是一个DBMS,它允许您声明FK约束但不强制执行它。在这方面,这样的DBMS是非关系型的。

如果您的意思是:RM是否允许业务规则说明发票客户也必须出现在客户名称中(即所有有效的数据库状态都是这样,即从发票客户到客户名称存在FK约束)不要向DBMS声明(例如通过FK声明)?

是。但这是一个糟糕的设计,因为它允许一些无效的状态。

答案 5 :(得分:0)

我认为这是否合适取决于您的设计。

发票应包含创建或发送发票时的数据。因此,它似乎需要与客户数据相关的数据,而不是直接使用外键,特别是如果您使用的是自然键。

例如,假设玛丽琼斯订购了一些东西并于2010年5月31日开具发票。2010年9月12日,她将自己的名字改为玛丽琼斯史密斯并转移到她丈夫的地址。作为时间图片的发票应保留Mary Jones的名称以及发送给它的原始地址。最好的是它可以保留当前客户和她的信息的链接(这就是为什么我会在客户表中有一个客户ID,因为名称更改和Customerid inteh incvoice表的FK)。但是当Mary Jones不再存在于客户表中时存储Mary Jones不仅可以,而且还需要了解实际发生的情况。

产品,价格和发票也是如此。您不希望发票现在反映价格,而是发票时的流程,即使这与现在的情况没有直接关系。在这种情况下,Product表可能更多是查找表而不是真正的父子关系。如果您将产品的所有详细信息存储在发票明细表中,那么您不需要产品的外键,只需要在下订单时查找活动产品。实际上,如果供应商更改了产品表或完全放弃了产品,那么过去的invopice的型号肯定不会出现在产品表中。但是你不想丢失过去购买过哪些产品的数据。

另一方面,如果关系要求数据与当前值保持一致,则正式的外键是最好的方法。