Подходит ли модуль Ltree PostgreSQL для потоковых комментариев?
-
03-07-2019 - |
Вопрос
Я подумываю об использовании PostgreSQL Модуль Ltree в моем приложении нужна помощь с потоковыми комментариями.Я уже некоторое время присматривался к нему, чтобы использовать для потоковых комментариев.Я полагаю, это помогло бы в случаях, когда вам нужно обновить узел и его дочерние элементы, например, когда вы хотите скрыть комментарий и ответы на него.
Я думаю, что ltree (или что-то в этом роде) было бы полезно, если бы оно было связано с традиционным списком смежности ("comment_id" / "parent_comment_id").
Прежде чем приступить к использованию ltree, мне интересно узнать несколько вещей:
- Используете ли вы или уже использовали ltree?Это то, что можно было бы назвать "готовым к производству"?
- Если да, то для решения каких проблем вы использовали его?Хорошо ли это сработало?
- Считаете ли вы, что это хорошо подходит для
многопоточной системы комментариев?
- Если вы использовали его, то что вы использовали для "текстовой" части пути?Вы настроили что-то вроде примера DMOZ, который они используют "Top.Astronomy.Cosmology", или основываете его на чем-то вроде первичного ключа "1.403.29.5"?
- Есть ли лучший способ сделать это?Я немного нервничаю, используя подход с вложенным списком - все, что я прочитал, говорит о том, что не все так просто с ОБНОВЛЕНИЯМИ или ВСТАВКАМИ (разве вам не нужно переупорядочивать все это?).Я также не специализируюсь в CS, и такая структура данных - это то, о чем я могу забыть в будущем.Кто-нибудь использует вложенные списки для комментариев или что-то в этом роде?
Если это может как-то помочь, вот схема, которую я рассматриваю:
CREATE TABLE comments (
comment_id SERIAL PRIMARY KEY,
parent_comment_id int REFERENCES comments(comment_id) ON UPDATE CASCADE ON DELETE CASCADE,
thread_id int NOT NULL REFERENCES threads(thread_id) ON UPDATE CASCADE ON DELETE CASCADE,
path ltree NOT NULL,
comment_body text NOT NULL,
hide boolean not null default false
);
Столбец "путь", используемый ltree, будет выглядеть примерно так:
<thread_id>.<parent_comment_id_#1>.<parent_comment_id_#2>.<my_comment_id>
Есть ли что-то неправильное в использовании первичных ключей в пути?Должен ли я включать собственный первичный ключ узла в путь?Если бы я это сделал, имело бы смысл наложить на него уникальный индекс, который служил бы ограничением?
Решение
- Да и да;
- Иерархия разделов в базе знаний (одна из реализаций);
- ДА;
Определение одной из рассматриваемых таблиц:
Table "knowledgebase.section"
Column | Type | Modifiers
----------------------------+--------------------------+-----------------------------------------------------------------------------
section_sid | integer | not null default nextval('knowledgebase.section_section_sid_seq'::regclass)
section | character varying | not null
description | character varying |
path | ltree | not null
is_active | boolean | not null default true
role_sid | integer | not null
last_modified_by | integer | not null
creation_datetime | timestamp with time zone | not null default now()
last_modification_datetime | timestamp with time zone | not null default now()
is_expanded | boolean | not null default false
section_idx | tsvector |
Indexes:
"section_sid_pkey" PRIMARY KEY, btree (section_sid)
"section_section_key" UNIQUE, btree (section)
"idxsection_idx" gist (section_idx)
"path_gist_idx" gist (path)
Foreign-key constraints:
"last_modified_by_fkey" FOREIGN KEY (last_modified_by) REFERENCES "user"."role"(role_sid) ON UPDATE CASCADE ON DELETE RESTRICT
"role_sid_fkey" FOREIGN KEY (role_sid) REFERENCES "user"."role"(role_sid) ON UPDATE CASCADE ON DELETE RESTRICT
Triggers:
section_idx_update BEFORE INSERT OR UPDATE ON knowledgebase.section FOR EACH ROW EXECUTE PROCEDURE tsearch2('section_idx', 'section')
Столбец "путь" использует первичный ключ в качестве метки.
Пример текущего содержимого этой таблицы (относительно первичного ключа и столбца "путь"):
section_sid | path
-------------+-------
53 | 34.53
56 | 56
55 | 29.55
35 | 35
54 | 34.54
37 | 30.37
... | ...
Другие советы
Я рекомендую всем, кто реализует иерархические отношения в SQL, прочитать Деревья и иерархии Джо Селко в SQL для Smarties.
Обход родительских дочерних ссылок произвольной глубины может быть очень неэффективным при использовании только parent_id.В книге описаны методы, которые делают этот доступ быстрым.
Одну стратегию (которую мне довелось использовать) также можно бесплатно найти в этой серии статей:
- Часть 1 (посмотрите раздел "Деревья в SQL") (Обратное звено)
- Часть 2 (Обратное звено)
- Часть 3 (Обратное звено)
- Часть 4 (Обратное звено)
Версия 8.4 PostgreSQL привнесет функциональность общих табличных выражений в ядро с WITH
и WITH... RECURSIVE
выражения.Если вы модифицируете старый код, возможно, вам захочется дождаться выхода версии 8.4, так как тогда вам не придется беспокоиться о каких-либо несовместимостях между Ltree и новым синтаксисом ядра.Если вы работаете со старым кодом или не хотите ждать версии 8.4, вам, вероятно, захочется убедиться, что вы пишете код, который легко переводится в новый синтаксис, особенно если вы меняете старую схему или разрабатываете новую.
Смотрите также: