用于在某个级别限制分层注释的数据库/代码设计?



我正在制作用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 级缩进。它可以工作,但不能帮助数据库执行。

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

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

最新更新