我正在使用PostgreSQL來使用鄰接列表方法對樹數據結構進行建模。我想是能夠存儲每片葉子上指示哪個組這棵樹屬於額外的數據:驗證樹建模爲鄰接列表的最佳方法,TRIGGER與CHECK約束
CREATE TABLE groups (
group_id integer PRIMARY KEY
);
CREATE TABLE leafs (
leaf_id integer PRIMARY KEY,
parent_id integer REFERENCES leafs ON DELETE CASCADE ON UPDATE CASCADE,
group_id integer REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE NOT NULL
);
我也想確保每個葉子只能連接到同一組。看起來這可以通過創建TRIGGER
或CHECK
約束來完成。我有兩個問題:
什麼是處理這種特殊情況下,
TRIGGER
或CHECK
約束的最有效/正確的方法? (以及在這兩者之間進行選擇的經驗法則是什麼)是否有更好的方法來強制執行此模型的一致性(或者可能是替代方法來模擬這些樹組)。
感謝,
代碼TRIGGER
版本:
CREATE OR REPLACE FUNCTION after_leaf_update()
RETURNS trigger AS
$$
BEGIN
IF (NEW.parent_id IS NOT NULL) AND (SELECT group_id FROM leafs WHERE leaf_id=NEW.parent_id) <> NEW.group_id THEN
RAISE EXCEPTION 'group_id of node/leaf does not match!!!';
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
CREATE TRIGGER leafs_consistency_check
BEFORE INSERT OR UPDATE
ON leafs
FOR EACH ROW
EXECUTE PROCEDURE after_leaf_update();
代碼CHECK
約束版本:
CREATE OR REPLACE FUNCTION leafs_consistency_check_constraint(prn_id integer, grp_id integer) RETURNS BOOL AS
$$
BEGIN
IF (prn_id IS NOT NULL) AND (SELECT group_id FROM leafs WHERE leaf_id=prn_id) <> grp_id THEN
RAISE EXCEPTION 'CHECK: group_id of node/leaf does not match!!!';
END IF;
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
ALTER TABLE leafs ADD constraint group_id_constraint check (leafs_consistency_check_constraint(parent_id, group_id));
你檢查了[PostgreSQL ltree模塊](https://www.postgresql.org/docs/current/static/ltree.html)嗎?它適用嗎?你能像'CREATE TABLE test(路徑ltree,YOUR_LABEL_HERE文本不是NULL)那樣做''就像'F.21.4。 Example'?通過使用「CREATE EXTENSION ltree」啓用數據庫模塊。 – flutter
你檢查了這個[SO問題]的答案嗎(https://stackoverflow.com/questions/14543173/postgresql-designing-a-tree-hierarchy-with-mixed-node-types-inheritance-does)?它有幫助嗎? – flutter
@ flutter - 感謝您的鏈接!我不知道ltree模塊 - 我會檢查出來! – Yatima