postgresql 在Postgres中,当使用LTREE时,是否可以去掉ID列,因为`LTREE`路径已经将ID作为最后一个标签?

wlsrxk51  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(149)

假设我有一个ID TEXT PRIMARY KEY列,这个ID用于在插入数据时为该行创建PATH LTREE列。因此ID最终成为路径中的最后一个标签。
那么,既然LTREE路径已经将ID作为最后一个标签,那么就完全去掉ID列是个明智的主意吗?
PATH LTREE可以作为主键吗?
这种做法有什么害处吗?

fnatzsnv

fnatzsnv1#

如果您查看ltree模块文档中的示例:

CREATE TABLE test (path ltree);
INSERT INTO test VALUES ('Top');
INSERT INTO test VALUES ('Top.Science');
INSERT INTO test VALUES ('Top.Science.Astronomy');
INSERT INTO test VALUES ('Top.Science.Astronomy.Astrophysics');
INSERT INTO test VALUES ('Top.Science.Astronomy.Cosmology');
INSERT INTO test VALUES ('Top.Hobbies');
INSERT INTO test VALUES ('Top.Hobbies.Amateurs_Astronomy');
INSERT INTO test VALUES ('Top.Collections');
INSERT INTO test VALUES ('Top.Collections.Pictures');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Stars');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Galaxies');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Astronauts');
CREATE INDEX path_gist_idx ON test USING GIST (path);
CREATE INDEX path_idx ON test USING BTREE (path);

您可以看到有两个条目的叶值为“Astronomy”。
如果您的ID总是用作最后一个标签,则在这种情况下它可能会有重复项(因此不再具有主键约束)。
您可以在最后一个标签上使用唯一索引来复制唯一性约束:

CREATE UNIQUE INDEX ON test (subpath(test.path, -1, 1));

但是,您将无法从此索引创建主键,因为它依赖于表达式。
我想这完全取决于您如何维护ID和ltree值之间的一致性。
可能值得保留ID列作为主键,并自动计算其值(例如通过触发器),无论何时插入和更新ltree值,都使用subpath(..., -1, 1),或者至少有某种形式的约束来确保它与路径一致。
这也取决于您对row locks的处理。
特别是,subpath(test.path, -1, 1)上的唯一索引不会完全复制主键索引的行为:

  • 目前,UPDATE情况下考虑的列集是那些在其上具有可在外键中使用的唯一索引的列(因此不考虑部分索引和表达式索引),但这可能会在未来发生变化。

相关问题