Разработка базы данных / кода для ограничения иерархических комментариев на определенном уровне? - PullRequest
0 голосов
/ 30 мая 2019

Я делаю небольшое приложение для комментирования, написанное на PHP как бэкэнд, React как фронтенд и PostgreSQL как база данных.У меня есть таблица comment, которая содержит все комментарии, и это таблица с самообращением.

\d+ comment:

     Column      |           Type           | Collation | Nullable |               Default               | Storage  | Stats target | Description 
-----------------+--------------------------+-----------+----------+-------------------------------------+----------+--------------+-------------
 id              | bigint                   |           | not null | nextval('comment_id_seq'::regclass) | plain    |              | 
 website_page_id | bigint                   |           | not null |                                     | plain    |              | 
 author_id       | bigint                   |           | not null |                                     | plain    |              | 
 parent_id       | bigint                   |           |          |                                     | plain    |              | 
 content         | text                     |           |          |                                     | extended |              | 
 deleted_date    | timestamp with time zone |           |          |                                     | plain    |              | 
 updated_date    | timestamp with time zone |           | not null |                                     | plain    |              | 
 created_date    | timestamp with time zone |           | not null |                                     | plain    |

На стороне клиента я делаю запрос на получение всех комментариев, сервер делаетВызовите запрос к базе данных, чтобы получить все комментарии и вернуть их в соответствующем формате, а затем я отрендерил его.

Вот JSON родительского комментария:

{
    id: 1
    author_id: 1
    content: "Some content"
    created_date: "2019-05-29 06:11:43+00"
    depth: 0
    parent_id: null
    replies: [...]
    updated_date: "2019-05-29 06:11:43+00"
    website_page_id: null
}

Таким образом, каждый комментарий в качестве параметра глубины, который я использую для определения идентификации (я не вкладываю комментарии рекурсивно, как comment -> replies -> comment -> replies, этотолько comment and all its replies. Я делаю дополнительную обработку в бэкэнде для создания этой формы, PostgreSQL возвращает только данные, как они есть с определением depth.

У меня есть форма для создания новых комментариев и ответов на существующие комментарии.далекие ответы могут вкладываться как можно дальше (не уверен насчет ограничений базы данных).

Вот мои проблемы:

  • Я не хочу вкладывать вечно, поскольку это снижает производительность(Я предполагаю). Действительно ли это? Кроме того, разумно ограничить его до уровня n по умолчанию, чтобы он не исчезал с экрана на стороне клиента.
  • Не уверен, где и каксделать ограничение. Должно ли оно быть на уровне базы данных, на стороне сервера или на стороне клиента?

У меня была только одна идея, как ее решить, но пока это не кажется элегантным решением. Вот оноэто:

Игнорировать тЕсли он вложен на уровне базы данных и просто ограничивает идентификаторы на стороне клиента, так что, если я определил максимальный уровень 5, то все, что выше, будет иметь 5-уровневую идентификацию.Это работает, но это не помогает производительности базы данных.

Я уверен, что есть другие возможные способы сделать это, помощь будет оценена!

1 Ответ

0 голосов
/ 05 июня 2019

Рекурсивные запросы (когда они используют индекс) действительно быстрые.Вероятно, потребуется больше времени для вложения результатов в Javascript.Ограничение вложенности больше для пользовательского интерфейса, и его не очень сложно получить:

    with recursive
      comment_node (comment_id, parent_id, level) as (
        select comment_id, comment_parent_id, 1::int4 as level
        from comment
        where website_page_id = $*
        union all
        select c.comment_id, c.comment_parent_id, parent.level + 1 as level
        from comment as c
          inner join comment_node as parent 
            on parent.comment_id = c.parent_id 
            and parent.level < 5
      )
    select c.comment_id, cn.level, c.comment_parent_id, c.content, a.name, ...
    from comment as c
      join comment_node as cn 
        using (comment_id)
      join author as a 
        using (author_id)

Ограничение вставки комментариев с уровнем вложенности 5 или более, вероятно, не является значимым ограничением базы данных, поскольку оно не нарушаетсогласованность данных.

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