PostgreSQL好友系统:接受请求时如何双向插入好友记录?
解决PostgreSQL好友请求接受时的双插入问题
嘿,作为常年和PostgreSQL打交道的开发者,我能get到你想实现的需求——接受好友请求时删掉请求记录,同时在好友表里插入双向关系。你的思路方向是对的,但CTE的写法有个小语法问题,导致没法完成双插入。
你的原写法问题在哪里?
你在INSERT里用了两个独立的SELECT子句:
INSERT INTO user_friends (user_id, friend_id) (SELECT sender_id, recipient_id FROM friend_request), (SELECT recipient_id, sender_id FROM friend_request);
这种语法在PostgreSQL里是不合法的,因为INSERT的SELECT部分需要是单一结果集,不能用逗号分隔多个查询。
正确的实现方式
你只需要把两个查询用UNION ALL合并成一个结果集,就能一次性插入两行数据了:
WITH deleted_request AS ( DELETE FROM friend_requests WHERE id = friendrequestid RETURNING sender_id, recipient_id ) INSERT INTO user_friends (user_id, friend_id) SELECT sender_id, recipient_id FROM deleted_request UNION ALL SELECT recipient_id, sender_id FROM deleted_request;
额外实用提醒
- 原子性保障:PostgreSQL的CTE和后续
INSERT会在同一个事务里执行,要么全部成功(删请求+插双向好友),要么全部回滚,完全不用担心出现“删了请求但没加上好友”的中间状态。 - 避免重复好友:建议给
user_friends表加个唯一约束,比如UNIQUE(user_id, friend_id),这样能防止重复插入同一对好友关系(比如用户误点多次接受的情况)。 - 命名优化:原CTE名字
friend_request和你的表名friend_requests(注意复数)太接近,容易混淆,我改成了deleted_request,你可以根据自己的习惯调整命名。
内容的提问来源于stack exchange,提问作者detas12
相关产品推荐
相关产品推荐

