使用主键和外键构建树
Using primary key & foreign key to build ltree
我对 postgres 很陌生,对 ltree 尤其陌生。
在网上搜索 ltree 时,我看到了通过链接字符构建树的示例。但是我想用主键和外键。
因此我构建了以下 table:
create table fragment(
id serial primary key,
description text,
path ltree
);
create index tree_path_idx on fragment using gist (path);
我想要 1.3.5 而不是 A.B.G。
在线示例中的根是这样添加的:
insert into fragment (description, path) values ('A', 'A');
我想要主键(我当时不知道)而不是 A。有办法吗?
添加 child 时我遇到了同样的问题:
insert into tree (letter, path) values ('B', '0.??');
我知道 parent 的 ID,但不知道我要附加的 child 的 ID。
有没有办法做到这一点,还是我完全偏离了轨道?
非常感谢!
您可以创建一个触发器,在每次插入之前修改 path
。例如,使用此设置:
DROP TABLE IF EXISTS fragment;
CREATE TABLE fragment(
id serial primary key
, description text
, path ltree
);
CREATE INDEX tree_path_idx ON fragment USING gist (path);
定义触发器:
CREATE OR REPLACE FUNCTION before_insert_on_fragment()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
new.path := new.path || new.id::text;
return new;
END $$;
DROP TRIGGER IF EXISTS before_insert_on_fragment ON fragment;
CREATE TRIGGER before_insert_on_fragment
BEFORE INSERT ON fragment
FOR EACH ROW EXECUTE PROCEDURE before_insert_on_fragment();
测试触发器:
INSERT INTO fragment (description, path) VALUES ('A', '');
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+------|
-- | 1 | A | 1 |
现在在id = 1下插入B:
INSERT INTO fragment (description, path) VALUES ('B', (SELECT path FROM fragment WHERE id=1));
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+------|
-- | 1 | A | 1 |
-- | 2 | B | 1.2 |
在 B 下插入 C:
INSERT INTO fragment (description, path) VALUES ('C', (SELECT path FROM fragment WHERE description='B'));
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+-------|
-- | 1 | A | 1 |
-- | 2 | B | 1.2 |
-- | 3 | C | 1.2.3 |
我对 postgres 很陌生,对 ltree 尤其陌生。 在网上搜索 ltree 时,我看到了通过链接字符构建树的示例。但是我想用主键和外键。
因此我构建了以下 table:
create table fragment(
id serial primary key,
description text,
path ltree
);
create index tree_path_idx on fragment using gist (path);
我想要 1.3.5 而不是 A.B.G。 在线示例中的根是这样添加的:
insert into fragment (description, path) values ('A', 'A');
我想要主键(我当时不知道)而不是 A。有办法吗?
添加 child 时我遇到了同样的问题:
insert into tree (letter, path) values ('B', '0.??');
我知道 parent 的 ID,但不知道我要附加的 child 的 ID。
有没有办法做到这一点,还是我完全偏离了轨道?
非常感谢!
您可以创建一个触发器,在每次插入之前修改 path
。例如,使用此设置:
DROP TABLE IF EXISTS fragment;
CREATE TABLE fragment(
id serial primary key
, description text
, path ltree
);
CREATE INDEX tree_path_idx ON fragment USING gist (path);
定义触发器:
CREATE OR REPLACE FUNCTION before_insert_on_fragment()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
new.path := new.path || new.id::text;
return new;
END $$;
DROP TRIGGER IF EXISTS before_insert_on_fragment ON fragment;
CREATE TRIGGER before_insert_on_fragment
BEFORE INSERT ON fragment
FOR EACH ROW EXECUTE PROCEDURE before_insert_on_fragment();
测试触发器:
INSERT INTO fragment (description, path) VALUES ('A', '');
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+------|
-- | 1 | A | 1 |
现在在id = 1下插入B:
INSERT INTO fragment (description, path) VALUES ('B', (SELECT path FROM fragment WHERE id=1));
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+------|
-- | 1 | A | 1 |
-- | 2 | B | 1.2 |
在 B 下插入 C:
INSERT INTO fragment (description, path) VALUES ('C', (SELECT path FROM fragment WHERE description='B'));
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+-------|
-- | 1 | A | 1 |
-- | 2 | B | 1.2 |
-- | 3 | C | 1.2.3 |