Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 使用PG upsert为“创建切换”;例如;邮递行动_Postgresql_Toggle_Upsert - Fatal编程技术网

Postgresql 使用PG upsert为“创建切换”;例如;邮递行动

Postgresql 使用PG upsert为“创建切换”;例如;邮递行动,postgresql,toggle,upsert,Postgresql,Toggle,Upsert,我正在尝试为帖子创建一个“Like”特性。 在我的web应用程序中,我有一个用户表和一个帖子表。我已经创建了一个名为Like_posts的新表,其中保存了哪些用户喜欢哪些帖子 一个核心约束是每个用户只能喜欢一篇文章一次。如果用户点击like按钮查看他/她已经喜欢的帖子,那么它将切换/删除like状态 基本逻辑是: 如果用户单击like和 如果like_posts已经包含一行user_id和post_id,请删除该行(即用户选择不喜欢以前喜欢的帖子), 否则,添加一个带有post\u id和use

我正在尝试为帖子创建一个“Like”特性。 在我的web应用程序中,我有一个用户表和一个帖子表。我已经创建了一个名为
Like_posts
的新表,其中保存了哪些用户喜欢哪些帖子

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

基本逻辑是:

如果用户单击like和
如果
like_posts
已经包含一行
user_id
post_id
,请删除该行(即用户选择不喜欢以前喜欢的帖子), 否则,添加一个带有
post\u id
user\u id
的新行

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

我知道我可以通过数组(posts表中的
用户id
)来完成,但我不想走这条路。使用不同数据展开和重新创建数组的性能不是很好,我真的不喜欢在PG中使用数组或
jsonb
(不喜欢API)

我想使用类似于upsert的东西,但据我所知,我只能执行“On Conflict(single column)”,而需要执行“On Conflict(col1和col2)”

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

基于@Laurenz Albe的优秀建议,我能够改进这种方法。 我现在在两列上有一个唯一的约束,如下所示:

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";

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

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_中使用NULL表示该行处于活动状态


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

您可以在两列上使用唯一或主键约束,并且可以在
on CONFLICT
子句中使用该约束。这样做的问题是没有其他用户会喜欢该帖子。在我的计划中,这些是有效的行
{row1={postid=1,userid=1}},{row2={postid=1,userid=2}}
我看不出问题
(postid,userid)
将是表的自然主键。您知道一个主键可以由几列组成,对吗?您也可以有一个int列,单击add1,而update查询有一个returning子句。然后使用mod%2。。。