我有两张桌子;朋友和用户。
Users表,略微简化:
CREATE TABLE users (
id bigserial NOT NULL,
fname text,
lname text,
username text,
created timestamp without time zone DEFAULT now(),
CONSTRAINT users_pkey PRIMARY KEY (id)
)
Friends表是一个连接表
CREATE TABLE friends
(
user_id bigint,
friend_id bigint,
accepted boolean DEFAULT false
)
因此,朋友表只是将一个用户映射到另一个用户,因此用户1可以是用户2的朋友。
我的问题:如何约束表格,使两对(1,2),(2,1)不插入表格?
我知道我可以unique (user_id , friend_id)
来阻止插入像(1,2)这样的重复行......
但是,如果(1,2)已经存在,如何阻止插入(2,1)?
答案 0 :(得分:3)
在表达式上使用索引:
create unique index unq_friends_user_friend
on (least(user_id, friend_id), greatest(user_id, friend_id));
编辑:
我需要详细说明,因为另一个答案。
请注意,这种方法涉及数据库中的一行代码(好吧,我承认我在答案中将其分为两部分;)
尝试在应用程序层复制此代码需要:
insert
之前检查结果的应用程序代码。update
也是如此。嗯,它留给读者作为练习如何处理更新,特别是多行更新。经历了所有这些麻烦之后,你仍然遇到了种族问题。两个线程可能会尝试插入相同的两个朋友。两者都没有看到冲突。两者都插入。现在,你有重复。
这使得单线解决方案真的很简单。