Только одна строка может иметь parent_id NULL:
CREATE TABLE simple21_page (
id integer NOT NULL,
name character varying(120) NOT NULL,
text text NOT NULL,
parent_id integer
);
Это дерево, и в нем должен быть ровно один корневой узел.
Я пробовал это, но это не работает:
create unique index on simple21_page (parent_id) where parent_id is null;
Возможно ли это с ограничением или уникальным индексом, или нужен триггер?
Вы почти там. Чтобы получить синглтон, вам нужно уникальное ограничение на постоянное значение:
CREATE UNIQUE INDEX ON simple21_page ((1)) WHERE parent_id IS NULL;
Еще один способ обеспечить такую уникальность — использовать COALESCE
и индексировать выражение:
CREATE UNIQUE INDEX ON simple21_page(COALESCE(parent_id, -1));
Значение, предоставленное в качестве замены, не должно выходить за рамки разрешенных значений.
INSERT INTO simple21_page VALUES (1, 'a', 'text', NULL);
-- success
INSERT INTO simple21_page VALUES (2, 'b', 'text', NULL);
-- ERROR: duplicate key value violates unique constraint "simple21_page_coalesce_idx"