postgresql - 插入原始表时聚合数据

标签 postgresql database-design relational-database

我目前正在构建一个类似论坛的应用程序。用户将能够看到最近的帖子以及总点赞数。如果用户对帖子感兴趣,他们也可以喜欢它并为总点赞数做出贡献。
规范化的方法是有两个表: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_count
  • 通过触发器更新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/

    相关文章:

    mongodb - N :M relationships? 的 MongoDB 中级联删除的推荐等效项是什么

    mysql - 用于保存统计数据并保存统计历史记录的数据库设计

    mysql - 如何设计一个每分钟增加很多行的数据库/表

    foreign-keys - 更好地使用外键或分配唯一的 ID?

    MYSQL - 获取所有选定类别中的行

    postgresql - JSONB 替换特定键的值 Postgresql

    postgresql - Postgres - 全文搜索接受表情符号

    mysql - 在多对多中查找最近加入的记录

    python - 如何使 sqlalchemy session 跟踪本地创建的对象中的所有更改?

    sql - 将日期转换为 varchar