数据库/代码设计可以在特定级别限制层次注释?

时间:2019-05-30 06:26:24

标签: php postgresql performance database-design

我正在制作一个小型的注释应用程序,用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级的任何东西都将具有5级标识。它可以工作,但是并不能帮助数据库提高性能。

我很确定还有其他可能的方法,我们将不胜感激!

1 个答案:

答案 0 :(得分:0)

递归查询(当它们利用索引时)非常快。将结果嵌套在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或更高的注释的插入可能不是有意义的数据库约束,因为它不会破坏数据的一致性。