知识卡片
SQL查询结果中重复的产生与"真重复"的辨识困境
内容
“只要基表没有重复行,重复问题就与我无关”这种想法是错的——即使输入的基表完全 不含重复(比如常用的suppliers-and-parts示例数据库本身没有重复行),同一个查询 问题用不同的SQL表述方式仍然可能在结果里产生带重复度差异的输出,这说明重复行 问题并不局限于基表设计层面,而是贯穿SQL查询执行的整个过程。禁止重复还有一条 [[关系是n维的而非二维的]]视角下的心理学论据:如果把关系类比成”n维空间中若干点 的集合”,重复行在这个类比里完全没有提供任何新信息——它们只是把同一个点重新 画了一遍,除了浪费笔墨没有任何额外价值。更实际的一条论据来自数据完整性:如果 一张表T本身就允许重复,那么就永远无法区分”业务上确实有意义的真重复”(比如同一 供应商真的对同一零件重复发运了两次货)和”纯粹因为数据录入失误产生的重复”(操作 员不小心把同一行输入两遍、或者不小心多敲了一次回车)——一旦两种重复在存储层 面变得不可区分,也就没有任何直接手段能在保留”第1行”的前提下单独删除误录入的 “第2行”,而这恰恰是应该删除的那一行。这个困境反过来印证了[[关系的精确定义与 关系命名之谜]]背后信息原理的立场:允许重复的设计天生就在制造无法挽回的信息 歧义。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第4章"不要重复,不要
null"4.2节"重复:深入讨论"(源文件:OEBPS/text00044.html)
- 结论依据:原文明确"即使输入表本身根本没有重复,同一查询的不同表述方式也可以
产生包含不同重复度的结果……如果你把表看作包含多个n维空间点的绘图的话,那么
重复行显然没有提供什么新的东西——它们只相当于把一个点画两遍……假设表T允许
重复。那么我们就无法分辨T中的'真'重复和数据输入错误导致的重复"。
- 原始内容:即使输入表本身根本没有重复,同一查询的不同表述方式也可以产生包含
不同重复度的结果……假设表T允许重复。那么我们就无法分辨T中的"真"重复和数据
输入错误导致的重复……没什么直接手段能在不删除"第1"行的情况下删除"第2"行。