PostgreSQL如何实施唯一性约束?它使用什么类型的索引?

14
我在阅读了关于Postgres中索引唯一性是实现细节的文档后,一直试图梳理唯一性和索引之间的关系:

向表添加唯一约束的首选方法是 ALTER TABLE ... ADD CONSTRAINT。使用索引来强制执行唯一约束可能被认为是不应该直接访问的实现细节。但是,需要注意的是,在唯一列上手动创建索引是没有必要的;这样做只会复制自动创建的索引。

所以,根据文档的说法,我将声明事物为唯一,并使用隐式索引 - 或者 - 创建一个索引,并不假设值是唯一的。这样做是否有错误?
从唯一性得到什么样的索引?考虑到只有btree才能接受唯一约束,并且unique隐式地创建一个索引,那么UNIQUE是否会创建一个btree索引?我不想无意中在哈希索引上运行范围。

1
我不想无意中在哈希索引上运行范围。但是请注意:这是一个实现细节。约束存在是为了强制/确保数据模型,它们并不关心性能本身。这是逻辑/语义上的区别。(顺便说一句:它确实是B树) - wildplasser
有趣的是,引用的偏好在PostgreSQL文档中已经消失,从v9.5开始。请参阅https://www.postgresql.org/docs/9.5/static/indexes-unique.html。 - Ethan
1个回答

23

创建索引时不要假设值是独一无二的

如果定义了唯一索引,那么可以安全地假设值是唯一的。这就是唯一约束的实现方式(目前以及将来的所有版本都是如此)。

定义 UNIQUE 约束与创建未指定索引类型的唯一索引几乎相同(除下面讨论的情况外)。并且,我quote the manual

选择包括btree、hash、gist和gin。默认方法是btree。

添加约束只是一种规范的方式,在未来版本中不会发生变动,在那些版本中它可能会被不同的实现方式取代。就是这样。

不,唯一约束只能在所有版本中(包括 PostgreSQL v14)使用基本的 btree 索引实现。引用段落 "ADD table_constraint_using_index" 在手册中:

索引不能有表达式列,也不能是部分索引。此外,它必须是具有默认排序顺序的 b 树索引。

其他区别?

  • 唯一约束可以被 延迟。而对于唯一索引则不可能。请查看 SET CONSTRAINTS 命令并点击链接获取更多信息。

相关:


B树索引是默认的...这是无论该索引如何生成(即INDEX vs UNIQUE)都是正确的。 - Finn
1
今天我学到了PostgreSQL的哈希支持很糟糕。http://blog.andrebarbosa.co/hash-indexes-on-postgres/ - Evan Carroll
@EvanCarroll:这将随着pg 10的推出而改变:https://www.postgresql.org/docs/devel/static/release-10.html#idm45609771377824 - Erwin Brandstetter
@ErwinBrandstetter 任何爱都是美好的,但是那些更改日志(和文档)似乎并没有暗示它们将可用作唯一索引,或者它们正在获得仅索引扫描(或者我可能错过了)。 - Evan Carroll
@Evan:没错,仍然没有唯一的哈希索引,只有B树。解决方法是在哈希表达式上创建B树索引,例如https://dba.stackexchange.com/a/115316/3684。至于仅索引扫描:*哈希*索引怎么可能成为候选项呢?原始值不在索引中。 - Erwin Brandstetter
显示剩余5条评论

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