我试图理解关系模型的规则,最初由Edgar Codd在1970年定义。
具体而言,我对参照完整性是否是他的关系模型的一部分感兴趣。我将尝试演示以下示例(只是为了使这个问题很漂亮):
客户
+------+------------
| Name | Address
|------+------------
| John | ....
| Mike | ....
| Kate | ....
+------+------------
发票
+------+------------
| ID | Customer
|------+------------
| 1 | John
| 2 | John
| 3 | Mary
+------+------------
现在,您可以看到,我们有一张发票,其中客户(外键)是 Mary 。这会违反他的关系模型吗?埃德加·科德会不会看到这个并说,哎呀,到底是什么?或者他会说,这完全没问题......
这是一个理论问题。
答案 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的型号肯定不会出现在产品表中。但是你不想丢失过去购买过哪些产品的数据。
另一方面,如果关系要求数据与当前值保持一致,则正式的外键是最好的方法。