代码之家  ›  专栏  ›  技术社区  ›  Rishav Sharan

使用pg upsert为post上的“like”操作创建切换

  •  0
  • Rishav Sharan  · 技术社区  · 7 年前

    我正在尝试为帖子创建“like”功能。 在我的网络应用程序中,我有一个用户表和一个帖子表。我创建了一个名为 Like_posts 我保存哪个用户喜欢哪个帖子。

    每个用户只能喜欢一次发帖的一个核心约束。如果用户点击他/她已经喜欢的帖子的like按钮,那么它将切换/删除like状态。

    基本逻辑是:

    如果用户单击like和
    如果 like_posts 已经包含一行 user_id 和 post_id ,删除行(即用户选择不喜欢以前喜欢的帖子)。 否则添加一个新行 臀后的 和 用户标识 .

    目前,我正在启动两个独立的查询,首先检查行是否存在,然后我的应用程序决定它是否应该插入或删除。考虑到我希望“like”是最常用的改变DB数据的特性之一,我真的希望在一个查询中实现它。

    我知道我可以通过阵列( liked_by ---GT; 用户标识 但我不想走那条路。使用不同数据展开和重新创建数组的性能不是很好,我真的不喜欢使用数组或 jsonb 在PG中(不喜欢API)。

    我想用一些类似于upsert的东西,但据我所知,我只能做“on conflict(single column)”,而我需要“on conflict(col1和col2)”。

    我的选择是什么?在我的数据库中设计“like”按钮切换的好方法是什么?

    基于@laurenz albe的优秀建议,我能够改进方法。 我现在对2列有一个独特的约束,如下所示:

    CREATE TABLE LIKE_POSTS (
        POST_ID TEXT NOT NULL,
        USER_ID TEXT NOT NULL,
        CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        DELETED_AT TIMESTAMP,
        CONSTRAINT "Unique_user_and_post_combo" PRIMARY KEY (POST_ID, USER_ID)
    );
    insert into like_posts (post_id, user_id) values (1,1);
    

    我仍然不确定如何执行删除操作。类似的东西;

    insert into like_posts (post_id, user_id) values (1,1) 
    returning "ON"
    ON CONFLICT ON CONSTRAINT Unique_user_and_post_combo
    DO DELETE RETURNING "OFF";
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Laurenz Albe    7 年前

    现在您有了一个主键约束,切换标志应该很简单:

    INSERT INTO like_posts (post_id, user_id, deleted_at)
       VALUES (1, 1, NULL) 
    ON CONFLICT ON CONSTRAINT "Unique_user_and_post_combo"
    DO UPDATE SET deleted_at = CASE WHEN deleted_at IS NULL
                                    THEN current_timestamp
                               END;
    

    这假定在 deleted_at 表示行处于活动状态。

    我建议您不要使用混合大小写名称(就像对约束所做的那样)。

    推荐文章