我正在尝试为帖子创建“赞”功能。
在我的网络应用程序中,我有一个供用户使用的表,一个供发布的表。我创建了一个名为Like_posts
的新表,在其中保存了哪个用户喜欢哪个帖子。
一个核心约束,即每个用户只能喜欢一次帖子。如果用户单击他/她已经喜欢的帖子的“喜欢”按钮,则它将切换/删除“喜欢”状态。
基本逻辑是:
如果用户单击“赞”和
如果like_posts
已包含带有user_id
和post_id
的行,请删除该行(即用户选择不喜欢以前喜欢的帖子),
否则用post_id
和user_id
添加新行。
目前,我正在触发2个单独的查询,首先要检查该行是否存在,然后我的应用程序决定是否应插入或删除该行。考虑到我希望“喜欢”成为使db数据变异的最常用功能之一,我真的很想在一个查询中做到这一点。
我知道我可以通过数组(posts表中的liked_by
-> user_id
)做到这一点,但是我不想走这条路。使用不同的数据来展开和重新创建数组不是很有效,我真的不喜欢在PG中使用数组或jsonb
(不喜欢API)。
我想使用upsert之类的东西,但是据我所知,我只能执行“冲突时(单列)”,而我需要“冲突时(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";
答案 0 :(得分:1)
现在您已经有了主键约束,切换标记应该很简单:
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
中使用NULL表示该行处于活动状态。
我建议您不要使用大小写混合的名称(就像您对约束所做的那样)。