Postgresql强制执行唯一的双向列组合

Postgresql强制执行唯一的双向列组合,postgresql,unique,combinations,Postgresql,Unique,Combinations,我正在尝试创建一个表,该表将在两个方向上强制执行相同类型的两列的唯一组合。例如,这将是非法的: col1 col2 1 2 2 1 我已经想到了这个,但它不起作用: database=> \d+ friend; Table "public.friend" Column | Type | Modifiers | Storage | Stats ta

我正在尝试创建一个表,该表将在两个方向上强制执行相同类型的两列的唯一组合。例如,这将是非法的:

col1 col2
   1    2
   2    1
我已经想到了这个,但它不起作用:

database=> \d+ friend;
                                Table "public.friend"
    Column    |           Type           | Modifiers | Storage  | Stats target | Description
--------------+--------------------------+-----------+----------+--------------+-------------
 user_id_from | text                     | not null  | extended |              |
 user_id_to   | text                     | not null  | extended |              |
 status       | text                     | not null  | extended |              |
 sent         | timestamp with time zone | not null  | plain    |              |
 updated      | timestamp with time zone |           | plain    |              |
Indexes:
    "friend_pkey" PRIMARY KEY, btree (user_id_from, user_id_to)
    "friend_user_id_to_user_id_from_key" UNIQUE CONSTRAINT, btree (user_id_to, user_id_from)
Foreign-key constraints:
    "friend_status_fkey" FOREIGN KEY (status) REFERENCES friend_status(name)
    "friend_user_id_from_fkey" FOREIGN KEY (user_id_from) REFERENCES user_account(login)
    "friend_user_id_to_fkey" FOREIGN KEY (user_id_to) REFERENCES user_account(login)
Has OIDs: no

是否有可能使用无约束或任何高级魔法来编写,只使用约束?

< P>你认为iTARLY扩展是魔法吗?< /P> 您需要为用户使用int键,而不是文本键

下面是一个可能的解决方案:

create extension intarray;

create table friendz (
  from_id int,
  to_id int
);

create unique index on friendz ( sort( array[from_id, to_id ] ) );

insert into friendz values (1,2); -- good

insert into friendz values (2,1); -- bad

Neil解决方案的一个不需要扩展的变体是:

create table friendz (
  from_id int,
  to_id int
);

create unique index ifriendz on friendz(greatest(from_id,to_id), least(from_id,to_id));
Neil的解决方案允许您使用任意数量的列

我们都依赖于使用表达式来构建文档化的索引

好家伙。非常简单,谢谢。在任何地方都找不到这个。我怎样才能用upsert使它工作?onconflict(col1,col2)表单似乎不起作用,因为这是一个索引。