PostgreSQL可以使用HASH排除约束以获得唯一性吗?

Iam*_*mIC 2 postgresql indexing unique-index ltree postgresql-10

由于哈希值比冗长的文本小,在我看来,为了确保列的唯一性,它们可能比b树更受欢迎。

仅出于确保唯一性的目的,是否有任何理由在PG 10中不符合以下条件?

CREATE TABLE test (
  path ltree,
  EXCLUDE USING HASH ((path::text) WITH =)
);
Run Code Online (Sandbox Code Playgroud)

我认为哈希冲突是在内部处理的。否则将毫无用处。

我将使用GiST索引来增强查询。

Erw*_*ter 5

我认为引用此手册可以总结一下:

尽管允许,但将B树或哈希索引与排除约束一起使用几乎没有意义,因为这无异于普通的唯一约束不能做得更好。因此,实际上,访问方法将始终是GiST或SP-GiST。

更何况您仍然想创建GiST索引。排除约束USING GIST将自动创建一个匹配的GiST索引作为实现细节。维护另一个甚至没有在查询中使用的低效哈希索引毫无意义。

对于简单的唯一性(WITH =),纯UNIQUEbtree索引更为有效。如果您的键很长,请考虑对哈希表达式使用唯一索引(使用任何不可变函数)以减小大小。喜欢:

CREATE UNIQUE INDEX test_path_hash_uni_idx ON test (my_hash_func(path));
Run Code Online (Sandbox Code Playgroud)

有关:

md5() 作为哈希函数将是一个简单的选择。

Postgres 10之前,不建议使用哈希索引。但是,有了最新的更新,情况已有所改善。Robert Haas(核心开发人员)在博客条目中总结了这一点:

CREATE INDEX test_path_hash_idx ON test USING HASH (path);
Run Code Online (Sandbox Code Playgroud)

las(在我的草案中忽略了),访问方法“哈希”尚不支持唯一索引。所以我仍然会在上面的哈希表达式上使用唯一索引。(但是没有减少信息的哈希函数可以完全保证密钥的唯一性,这可能会或可能不会成为问题。)

  • “EXCLUDE USING HASH”解决方案似乎有一些优点: 1. 快速且小的哈希函数上的唯一 btree 索引将导致冲突错误。2. 实际上无冲突的哈希函数可能(?)导致明显的速度减慢 3. `EXCLUDE` 创建一个简单的哈希索引,也可以直接由查询使用。相反,哈希函数上的 btree 索引仅由显式执行“where md5(ltree1) = md5(ltree2) and ltree1 = ltree2”之类的查询使用。编辑:我的评论是关于值对于普通 UNIQUE btree 来说太大的情况。 (2认同)
  • @ErwinBrandstetter:假设哈希索引使用 `hash$type` 函数系列(不确定),[它似乎确实在内部处理冲突](https://www.db-fiddle.com/f/hxQZjZmCSKdQiBQJuKoq2S/2) 。我也期望这种行为,因为我们在语义上要求 Postgres 排除“=”运算符,而不是哈希值。 (2认同)