Является ли модуль PostgreSQL Ltree подходящим для потоковых комментариев? - PullRequest
9 голосов
/ 02 марта 2009

Я рассматриваю возможность использования модуля Ltree в PostgreSQL в моем приложении, чтобы помочь с многопоточными комментариями. Я уже давно смотрю на это, чтобы использовать его для комментариев. Я полагаю, что это поможет в случаях, когда вам нужно обновить узел и его дочерние элементы, например, когда вы хотите скрыть комментарий и его ответы.

Я думаю, что дерево (или что-то подобное) было бы полезно, если бы оно было связано с традиционным списком смежности ("comment_id" / "parent_comment_id").

Прежде чем окунуться в использование ltree, мне интересно несколько вещей:

  1. Вы использовали или использовали дерево? Это то, что можно назвать «готовым к производству»?
  2. Если да, то какие проблемы вы использовали для его решения? Это хорошо сработало?
  3. Как вы думаете, это хорошо подходит для многопоточная система комментариев?
    1. Если вы использовали его, что вы использовали для «текстовой» части пути? Вы настроили что-то вроде примера DMOZ, в котором они используют «Top.Astronomy.Cosmology» или основали его на чем-то вроде первичного ключа «1.403.29.5»?
    2. Есть ли лучший способ сделать это? Я немного нервничаю, используя подход с вложенными списками - все, что я прочитал, говорит о том, что не все так просто с UPDATES или INSERTS (вам не нужно переупорядочивать все это?). Я также не майор 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
);

Столбец "path", используемый ltree, будет выглядеть примерно так:

<thread_id>.<parent_comment_id_#1>.<parent_comment_id_#2>.<my_comment_id>

Что-то не так с использованием первичных ключей в пути? Должен ли я включить собственный первичный ключ узла в путь? Если бы я это сделал, имеет ли смысл ставить на него уникальный индекс, чтобы он служил ограничением?

Ответы [ 3 ]

6 голосов
/ 03 марта 2009
  1. Да и да;
  2. Иерархия разделов в базе знаний (одна из реализаций);
  3. Да,

Определение одной из рассматриваемых таблиц:

                                                   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
          ... | ...
4 голосов
/ 04 марта 2009

Я рекомендую всем, кто реализует иерархические отношения в SQL, прочитать Деревья и иерархии Джо Селко в SQL для умных .

Обход произвольных глубинных родительских дочерних ссылок может быть очень неэффективным при использовании только parent_id. Книга описывает методы, которые делают этот доступ быстрым.

В этой серии статей можно бесплатно найти одну стратегию (которую я использую):

2 голосов
/ 03 марта 2009

Версия 8.4 PostgreSQL будет приносить функциональность Common Table Expressions в ядро ​​с выражениями WITH и WITH... RECURSIVE. Если вы модифицируете старый код, вы можете подождать, пока не выйдет 8.4, так как вам не придется беспокоиться о несовместимости между Ltree и новым синтаксисом ядра. Если вы работаете со старым кодом или не хотите ждать 8.4, вы, вероятно, захотите написать код, который легко переносится на новый синтаксис, особенно если вы меняете старую схему или проектируете новую. один.

Смотри также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...