Использование первичного ключа и внешнего ключа для построения дерева - PullRequest
0 голосов
/ 22 февраля 2019

Я довольно новичок в postgres и особенно новичок в ltree.Поиск в сети ltree привел меня к примерам, где дерево строилось цепочкой символов.Но я хочу использовать первичный ключ и внешний ключ.

Поэтому я строю следующую таблицу:

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

Вместо ABG я хочу иметь 1.3.5.Корень в примерах онлайн добавляется так:

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

Вместо ИИ хочу иметь первичный ключ (чего я не знаю в данный момент).Есть ли способ сделать это?

При добавлении ребенка у меня возникла та же проблема:

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

Я знаю идентификатор родителя, но не ребенка, которого я хочу добавить.

Есть ли способ сделать это или я полностью сбился с пути?

Большое спасибо!

1 Ответ

0 голосов
/ 22 февраля 2019

Вы можете создать триггер, который изменяет 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 |

Теперь вставьте B под id = 1:

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 |

Вставить C под B:

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 |
...