Database 为什么在唯一索引中有非唯一项?(PostgreSQL 9.0)

Database 为什么在唯一索引中有非唯一项?(PostgreSQL 9.0),database,postgresql,indexing,unique,unique-index,Database,Postgresql,Indexing,Unique,Unique Index,我的postgresql 9.0 db中有一个基于函数的唯一索引。我还没有通过我尝试的任何手动测试使它失败,但是当我查询它时,我在db中看到了一些重复项 看看这个: Index: "users_screen_name_idx" UNIQUE, btree (lower(screen_name::text)) # select lower(screen_name), count(1) from users group by lower(screen_name) having count(1) &

我的postgresql 9.0 db中有一个基于函数的唯一索引。我还没有通过我尝试的任何手动测试使它失败,但是当我查询它时,我在db中看到了一些重复项

看看这个:

Index: "users_screen_name_idx" UNIQUE, btree (lower(screen_name::text))

# select lower(screen_name), count(1) from users group by lower(screen_name) having count(1) > 1;

 lower         | count 
---------------+-------
 xxx xxx 3735  |     2
 xxx xxx 37383 |     2
 ... (36 more) ...
               | 17254
(39 rows)

你知道这是怎么发生的吗?我知道NULL不是唯一的,这不是问题所在,而是其他38行。

如果您一直在手动尝试使数据库系统失败,则可能是您遇到了索引损坏。尝试重建索引(
REINDEX
)。如果由于重复的值而失败,那么就是这样。

您可以在PostgreSQL中禁用触发器。这是一个非常危险的选项,但实际上可以用于将数据添加到违反唯一或外键约束的表中。

如果使用表继承,则可能会导致这种情况,因为唯一约束不会被继承。事实上,这可能是这类事情最常见的原因,而不是数据损坏

如果删除并重新创建索引,它会失败吗


如果没有,你的复制品就在别处

有没有办法作为一个主动过程来检查索引损坏,而不进行重新索引并查看它是否失败?没有,但常规真空将进行一些偶然检查。我们禁用触发器的唯一时间是在数据库恢复中(我们需要这样做,以便我们可以导入数据库而不获取外键错误)。或者,您可以使用延迟FK约束,并在单个事务中导入数据库。这是一个可怕的错误。我真的希望9.3能够在系统开始返回不正确的结果之前,通过校验和之类的方式获得一些内置的验证。我还想知道数据是否在ZFS文件系统中,是否会捕获或阻止此类内容。