【问题标题】:Database/code design for limiting hierarchical comments at certain level?用于在特定级别限制分层注释的数据库/代码设计?
【发布时间】:2019-10-15 18:54:17
【问题描述】:

我正在制作用 PHP 编写的小型评论应用程序作为后端,React 作为前端,PostgreSQL 作为数据库。我有表comment,它包含所有 cmets,它是自引用表。

\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    |

在客户端我请求获取所有 cmets,后端对数据库进行 recusive 查询以获取所有 cmets 并以适当的格式返回它们,然后我呈现它。

这是父评论的 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那样递归嵌套cmets,它只是comment and all its replies。我在后端做了额外的处理来制作这个表格,PostgreSQL只返回depth 定义中的数据。

我有一个用于创建新 cmets 和回复现有 cmets 的表单。到目前为止,回复可以尽可能多地嵌套(不确定数据库限制)。

这是我的担忧:

  • 我不想永远嵌套,因为它会影响性能(我假设)。真的吗?此外,默认情况下将其限制在n 级别是合理的,因此它不会在客户端屏幕上消失。
  • 不确定在哪里以及如何进行限制。是否应该在数据库级别、后端或客户端?

我只有一个想法如何解决它,但到目前为止它似乎并不是一个优雅的解决方案。这里是:

忽略它嵌套在数据库级别并且仅限制客户端的标识,因此如果我将 5 级定义为最大值,那么任何高于该级别的都将具有 5 级标识。它可以工作,但对数据库性能没有帮助。

我很确定还有其他可能的方法可以做到这一点,我们将不胜感激!

【问题讨论】:

    标签: php postgresql performance database-design


    【解决方案1】:

    递归查询(当它们利用索引时)非常快。将结果嵌套在 Javascript 中可能需要更多时间。嵌套限制更多的是 UI 并且不是很难获取:

        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 或更高的 cmets 的插入可能不是一个有意义的数据库约束,因为它不会破坏数据的一致性。

    【讨论】:

      猜你喜欢
      • 2011-04-23
      • 1970-01-01
      • 2021-01-01
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      相关资源
      最近更新 更多