1

我对 postgres 很陌生,尤其是对 ltree 很陌生。在网上搜索 ltree 给我带来了通过链接字符构建树的示例。但我想使用主键和外键。

因此我建立了下表:

create table fragment(
        id serial primary key,
        description text,
        path ltree
    );
create index tree_path_idx on fragment using gist (path);

我想要 1.3.5 而不是 ABG。在线示例中的根添加如下:

insert into fragment (description, path) values ('A', 'A');

而不是 AI 想要拥有主键(当时我不知道)。有没有办法做到这一点?

添加孩子时,我遇到了同样的问题:

insert into tree (letter, path) values ('B', '0.??');

我知道父母的 id,但不知道我想附加的孩子的 id。

有没有办法做到这一点,或者我完全偏离了轨道?

非常感谢!

4

1 回答 1

4

您可以创建一个触发器,该触发器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 |
于 2019-02-22T02:47:45.217 回答