Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么SQL标准允许重复行?_Sql_Relational Database - Fatal编程技术网

为什么SQL标准允许重复行?

为什么SQL标准允许重复行?,sql,relational-database,Sql,Relational Database,关系模型的关键之一是元组(行)所需的唯一性: 通过指定包含表的名称、包含列的名称和包含行的主键值,数据库中的每个标量值必须在逻辑上可寻址 在SQL世界中,这意味着表中不可能存在所有列值相等的两行。如果没有有意义的方法来保证唯一性,那么可以向表中提供代理键 当第一个SQL标准发布时,它没有定义这样的限制,从那时起就一直如此。这似乎是所有邪恶的根源 是否有任何有意义的理由决定这样做?在现实世界中,没有这样的限制在哪里可以证明是有用的?它是否超过了缺点?在SQL世界中,这意味着表中不可能存在所有列值都

关系模型的关键之一是元组(行)所需的唯一性:

通过指定包含表的名称、包含列的名称和包含行的主键值,数据库中的每个标量值必须在逻辑上可寻址


在SQL世界中,这意味着表中不可能存在所有列值相等的两行。如果没有有意义的方法来保证唯一性,那么可以向表中提供代理键

当第一个SQL标准发布时,它没有定义这样的限制,从那时起就一直如此。这似乎是所有邪恶的根源


是否有任何有意义的理由决定这样做?在现实世界中,没有这样的限制在哪里可以证明是有用的?它是否超过了缺点?

在SQL世界中,这意味着表中不可能存在所有列值都相等的两行,这是事实。除非该元组的所有属性都与另一个元组匹配,否则它不是重复的元组,即使它仅在主键列上有所不同


这就是为什么我们应该定义其他键(
unique key
)列以及主键,以将每个记录标识为唯一的。

虽然这通常是表的工作方式,但将其作为规则并不实际


要遵循此规则,表必须始终具有主键。这意味着您不能只删除表上的主键,然后添加另一个主键。您需要同时进行这两项更改,以便表永远不会缺少主键。

您假设数据库仅用于存储关系数据;这当然不是它们的用途,因为实际的考虑总是会赢的

不需要主键的一个明显的例子是某种描述的“状态”日志(天气/数据库/任何东西)。如果您不打算从此表中查询单个值,则可能不希望有主键,以避免必须等待插入到键中。如果您有一个用例从这个表中提取一个值,那么当然,这将是一个糟糕的解决方案,但有些人并不需要它。如果绝对必要,您可以在之后添加代理密钥

另一个例子是写密集型应用程序需要告诉另一个进程做一些事情。此辅助进程每N分钟/小时/任意时间运行一次。一次性对N百万条记录执行重复数据消除比检查表中每次插入的唯一性要快(相信我)

作为关系数据库出售的内容并不仅仅用作关系数据库。它们被用作日志、键值存储、图形数据库等。它们可能不具备竞争对手的所有功能,但有一些具备这些功能。通常,拥有一个不适合您的关系模型的表比创建一个完整的其他数据库并遭受数据传输性能损失更简单


tl;dr人们在数学上并不完美,因此不会总是使用数学上完美的方法来做事。委员会是由人组成的,有时可以意识到这一点。

简而言之,SQL不是关系型数据库,SQL DBMS不是关系型数据库

重复行是SQL数据模型的一个基本部分,因为SQL语言并没有真正尝试实现关系代数。SQL使用基于bag(多集)的代数。在关系代数中,查询和其他操作的结果是始终具有不同元组的关系,但是SQL DBMS没有仅处理关系的特权。鉴于SQL语言的这一基本“特性”,SQL数据库引擎需要有处理和存储重复行的机制


为什么SQL是这样设计的?一个原因似乎是关系模型在当时是一个信仰上的巨大飞跃。关系模型是一个超前于时代的想法。另一方面,SQL过去和现在都深深植根于三十年前的系统中。

该语言的最早版本没有任何形式的约束,包括键。因此,唯一性根本无法强制执行。当对约束(特别是键)的支持后来被添加到语言中时,操作系统已经编写好了,没有人想破坏向后兼容性。因此,它(允许复制)一直存在

休·达文(Hugh Darwen)的书《SQL:A comparative survey》(可从bookboon免费获得)中有许多关于历史背景的简洁的小主题,就像这一个


(编辑:在语言的最初版本中不支持约束的原因大概是,当时Codd的主要愿景是查询语言将实际上是一种查询(即只读)语言,DBMS的“关系”方面将限于具有“关系包装层”从这个角度来看,语言本身不存在“更新”的问题,因此不需要定义约束,因为这些约束是在“现有的非关系数据库”中定义和实施的。但这种方法很早就被放弃了。)

有意义的原因是实用性。事实证明,不断检查和删除重复项是一项昂贵的操作。同意@GordonLinoff的观点,在实践中,使用具有唯一约束的强键远远优于不断检查和删除重复项。磁盘很便宜,所以实现一个常量签出的成本不会超过存储潜在重复项的额外成本。我想添加,这不是关系数据中所有问题的根源