关系模型的core rules之一是元组(行)所需的唯一性:
通过指定包含表的名称,包含列的名称以及主键的值,数据库中的每个单独标量值都必须在逻辑上可寻址。包含行。
在SQL世界中,这意味着表中永远不会存在两行,所有列值都相等。如果没有有意义的方法来保证唯一性,可以在表格中显示代理键。
当第一个SQL标准发布时,它没有定义这样的限制,从那时起它就像这样。这似乎是所有邪恶的根源。
为什么决定这样做有什么有意义的理由吗?在实际的世界中,没有这种限制可以证明是有用的吗?它超过了缺点吗?
答案 0 :(得分:4)
简短的回答是SQL不是关系型的,而SQL DBMS不是关系型DBMS。
重复行是SQL数据模型的基本部分,因为SQL语言并没有真正尝试实现关系代数。 SQL使用基于包(multiset)的代数代替。关系代数中的查询和其他操作的结果是始终具有不同元组的关系,但SQL DBMS不具有仅处理关系的奢侈。鉴于这一基本功能"在SQL语言中,SQL数据库引擎需要有处理和存储重复行的机制。
为什么SQL这样设计?一个原因似乎是关系模型在当时是一个太大的信念飞跃。关系模型是一个远远超前的想法。另一方面,SQL曾经并且仍然非常植根于三十年前的系统。
答案 1 :(得分:3)
该语言的第一个版本没有任何形式的约束,包括键。因此,不能强制执行唯一性。稍后当对语言添加对约束(特别是键)的支持时,已经编写了操作系统,并且没有人想要破坏向后兼容性。所以它(允许重复)一直存在。
许多关于历史背景的简洁主题,就像这个一样,可以在Hugh Darwen的书中找到" SQL:比较调查" (可从bookboon免费获得)。
(编辑:可能是原因为什么在该语言的第一版中没有对约束的支持,当时,Codd的主要愿景是查询语言实际上将是一个查询(即只读)语言,并且DBMS的"关系"方面将限于拥有一个"关系包装层&#34 ;在结构中不关系的现有数据库。从这个角度来看,没有问题"更新"在语言本身,因此不需要定义约束,因为那些是在现有的非关系型数据库中定义和实施了#34;但是这种方法很早就被放弃了。)
答案 2 :(得分:2)
您假设数据库仅用于存储关系数据;这肯定不是他们所使用的,因为实际的考虑总会赢。
一个不需要主键的明显例子是"状态"记录一些描述(天气/数据库/等等)。如果您永远不会查询此表中的单个值,则可能不希望拥有主键以避免必须等待插入到密钥中。如果你有一个用例来从这个表中获取单个值,那么肯定,这将是一个糟糕的解决方案,但是有些人根本不需要它。如果绝对必要,您可以随后添加代理密钥。
另一个例子是写密集型应用程序需要告诉另一个进程做某事。这个辅助过程每N分钟/小时/无论如何运行。对N0000个记录进行一次性重复数据删除比检查每个插入表中的唯一性更快(相信我)。
作为关系数据库销售的产品不仅仅用作关系数据库。它们被用作日志,键值存储,图形数据库等。它们可能没有竞争对手的所有功能,但是有些人可以做到并且通常更简单的是没有一个表没有。适合您的关系模型而不是创建整个其他数据库并遭受数据传输性能损失。
tl; dr 人们在数学上并不完美,因此不会总是使用数学上完美的做法。委员会由人组成,有时可以实现这一点。
答案 3 :(得分:0)
虽然这通常是表的工作原理,但通常将它作为规则是不切实际的。
要遵循该规则,表必须始终具有主键。这意味着您不能只删除表上的主键,然后添加另一个。您需要同时进行两次更改,以便表永远不会没有主键。
答案 4 :(得分:-1)
在SQL世界中,这意味着表中永远不会存在两行,所有列值都相等且为真。除非该元组的所有属性都与另一个属性匹配,否则即使它的剂量仅与主键列不同,它也不是重复的。
这就是为什么我们应该定义其他密钥(unique key
)列以及主键以将每条记录标识为唯一。