PostgreSQL唯一索引不唯一?

5

我有一个有12列的唯一索引表。\d sales显示sales_uq UNIQUE,btree(a1,a2,a3,...a12)

我执行以下查询:

SELECT a1, a2, a3, ... a12 FROM sales GROUP BY a1, a2, a3, ... a12 HAVING count(1) > 1;

我得到了许多结果。这怎么可能?!索引可能存在,但被禁用了吗?或者有一些NULL值的问题?或者浮点数的问题(索引中的两列是double precision类型)?

2个回答

12
因为两个NULL不相等,所以它们会在UNIQUE约束中玩一些有趣的游戏。
请参阅PostgreSQL文档中UNIQUE约束的最后一段:
总的来说,当表中有两行或更多行的所有包含在约束中的列的值相等时,就会违反唯一约束。然而,在这种比较中,两个空值不被认为是相等的。这意味着即使存在唯一约束,仍然可以存储包含至少一个受约束列中的空值的重复行。

1
该死,这太糟糕了。我知道 NULL 不等于 NULL,但出于某种原因,我以为在索引中会有所不同。 :) - ibz
@ionut bizau - 当然,真正有趣的是,为了GROUPing目的,NULL被分组在一起。正如文档所述,一些其他服务器(例如SQL Server)只实现允许单个NULL的UNIQUE约束(尽管这违反了ANSI SQL规范)。 - Damien_The_Unbeliever

2
一个双精度浮点数是不精确的, 这就是为什么可能会发生这种情况。使用精确数据类型,你就不会遇到这样的问题了。

虽然这并没有解决我的问题,但这是一个非常好的观点。我会考虑改用NUMERIC数据库。谢谢。 - ibz
例如,45.454545454是否总是导致相同的不精确值,从而导致两行列相同?还是说您在说45.454545454将导致45.455和45.454这两种情况?当然,我使用的数字仅用于讨论目的。 - Kuberchaun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接