我有一个评论系统,用户可以在其中评论帖子,然后用户可以回复那些顶级评论。这就是嵌套的扩展:用户不能回复回复。
顶级评论和回复位于同一个表中。它们几乎完全相同。顶级评论有一个post_id
,回复有一个parent_id
。我在表上使用了一个约束来确保这些列中的一列对每一行都有一个值。
CREATE TABLE comments (
id integer NOT NULL,
post_id integer,
author_id integer NOT NULL,
body text,
created_at timestamp without time zone,
updated_at timestamp without time zone,
parent_id integer,
CONSTRAINT must_have_media_item_xor_parent CHECK ((((media_item_id IS NULL) AND (parent_id IS NOT NULL)) OR ((media_item_id IS NOT NULL) AND (parent_id IS NULL))))
);
现在我想统计特定帖子上的所有评论,包括回复。查询
SELECT count(*)
FROM comments
WHERE comments.post_id = 123
告诉我#123 帖子有多少顶级评论。查询
SELECT count(*)
FROM comments
JOIN comments AS replies ON replies.parent_id = comments.id
WHERE comments.post_id = 123
告诉我有多少回复。我可以两者都做并将它们加在一起,但这听起来很重,希望没有必要。
一种避免来自第二个查询的自连接的解决方案是也设置post_id
on 回复,使值非规范化。然后第一个查询将计算所有这些。如果我这样做,我真的很想在数据库中进行某种一致性检查,以确保我做对了。
有没有办法让 Postgres 在设置post_id
时将其值限制为其父级的值parent_id
?正常约束似乎只能查看单行。
或者,是否有另一种好方法可以一口气统计所有评论?