我目前正在构建一个类似论坛的应用程序。用户将能够看到最近的帖子以及总点赞数。如果用户对帖子感兴趣,他们也可以喜欢它并为总点赞数做出贡献。
规范化的方法是有两个表:user_post(contains id, metadata ...)
, liked_post(which includes the user id + post id)
.当帖子被查询时,喜欢计数将通过 COUNT()
确定。关于 liked_post
的声明按帖子 ID 分组的表格。
我正在考虑另一种方法,它不需要在潜在的巨大 table 上进行分组。那将是添加一个 like_count
列到 user_post
表并打破规范化。当新的 like_post 条目被插入或删除时,此列将始终更新。这意味着:每次用户喜欢一个帖子 -> user_post
上都会有更新表(增加 like_count
列)+ 在 liked_post
中插入/删除实体表(在 App 层带有触发器或代码)。
请问这个aggregation on the fly
方法有什么缺点,除了一致性问题?这将启用非常简单和快速的选择查询,但我不确定额外的更新是否会成为问题。
你怎么看 ?
我真的对性能影响感兴趣,而不是你是否应该从项目开始就这样做。
最佳答案
你的想法是正确的并且被广泛使用。您将面临的问题:
like_count
已验证?这个数字可以延迟或以某种方式近似吗? 一般来说,您可以通过以下方式执行此操作
如果您想获得正确的确切值,您可以通过触发器累积这些总和,或者以编程方式确保喜欢计数更新始终在插入到 like_posts 的同一事务中
使用触发器可能是这样的:
CREATE FUNCTION public.update_like_count() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE user_post SET user_post.liked_count = user_post.liked_count + 1
WHERE user_post.id = NEW.post_id;
RETURN NEW;
END;
$$;
CREATE TRIGGER update_like_counts
AFTER INSERT ON public.liked_posts
FOR EACH ROW EXECUTE PROCEDURE public.update_like_count();
你也应该处理 AFTER DELETE
通过单独的触发器。请注意,根据事务隔离级别,您可能会在此处输入并发问题(如果同时进行 2 次插入 - 对于两个事务,like_count 可能完全相同)并以无效总数结束。
关于postgresql - 插入原始表时聚合数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67859842/