Я играл с ltree, который является модулем Contributor PostgreSQL, чтобы узнать, подходит ли он для потоковых комментариев. Вы создать столбец в вашей таблице, которая хранит путь и создать индекс ltree на нем .. Вы можете выполнять запросы, как это:
ltreetest=# select path from test where path ~ '*.Astronomy.*';
path
-----------------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
Top.Collections.Pictures.Astronomy
Top.Collections.Pictures.Astronomy.Stars
Top.Collections.Pictures.Astronomy.Galaxies
Top.Collections.Pictures.Astronomy.Astronauts
я не играл с ним достаточно, чтобы определить, насколько хорошо он выполняет с такими вещами, как вставки, обновления или удаления.Я предполагаю, что удаление объекта будет выглядеть так:
DELETE FROM test WHERE path ~ '*.Astronomy.*';
Я думаю, резьбовая комментарий таблица может выглядеть следующим образом:
CREATE SEQUENCE comment_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 78616
CACHE 1;
CREATE TABLE comments (
comment_id int PRIMARY KEY,
path ltree,
comment text
);
CREATE INDEX comments_path_idx ON comments USING gist (path);
Вкладыш бы грубо (и непроверенные-LY) выглядит следующим образом:
CREATE FUNCTION busted_add_comment(text the_comment, int parent_comment_id) RETURNS void AS
$BODY$
DECLARE
INT _new_comment_id; -- our new comment_id
TEXT _parent_path; -- the parent path
BEGIN
_new_comment_id := nextval('comment_id_seq'::regclass);
SELECT path INTO _parent_path FROM comments WHERE comment_id = parent_comment_id;
-- this is probably busted SQL, but you get the idea... this comment's path looks like
-- the.parent.path.US
--
-- eg (if parent_comment_id was 5 and our new comment_id is 43):
-- 3.5.43
INSERT INTO comments (comment_id, comment, path) VALUES (_new_comment_id, the_comment, CONCAT(_parent_path, '.', _new_comment_id));
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Или что-то. В основном путь - это просто иерархия, состоящая из всех основных ключей.
Вы * можете * сделать это для иерархии произвольной глубины, используя стандартный SQL по схеме типа «родительский-id-foreign-key»: вы можете использовать рекурсивное общее табличное выражение. По общему признанию, PostgreSQL поддерживал это только с 8.4, который выходил через несколько месяцев после этого потока, но я думал, что это может быть полезным дополнением. FWIW, Firebird, MS SQL Server и DB2 поддерживают рекурсивные CTE, хотя версия MSSQL ограничена. Oracle имеет свой собственный странный синтаксис. –