POSTGRES多对一约束

时间:2017-07-24 20:00:39

标签: postgresql

我有两个colums,foo和bar。 foo只能存在一个条形,但可以存在n次。如果我尝试使用不同的bar值插入foo,则需要失败。

 foo | bar
----------
  a  |  a
  a  |  a
  b  |  a
  b  |  a
  b  |  b  <---  this needs to fail.

我该如何解决这个问题?

在某种程度上,这个问题的正确语言是什么?

1 个答案:

答案 0 :(得分:3)

您可以使用EXCLUDE约束 使用扩展程序btree_gist

CREATE EXTENSION btree_gist;

您可以定义表格

CREATE TABLE fb (
  foo text,
  bar text,
  EXCLUDE USING gist (foo WITH =, bar WITH <>)
);

以下插入即可:

#= INSERT INTO fb VALUES ('a', 'a'), ('a', 'a'), ('b', 'b');
INSERT 0 3
Time: 1,392 ms
#= SELECT * FROM fb;
┌─────┬─────┐
│ foo │ bar │
├─────┼─────┤
│ a   │ a   │
│ a   │ a   │
│ b   │ b   │
└─────┴─────┘
(3 rows)

但插入('b', 'a')元组失败,因为'b'已经有bar = 'b'行。

#= INSERT INTO fb VALUES ('b', 'a');
ERROR:  23P01: conflicting key value violates exclusion constraint "fb_foo_bar_excl"
DETAIL:  Key (foo, bar)=(b, a) conflicts with existing key (foo, bar)=(b, b).
SCHEMA NAME:  public
TABLE NAME:  fb
CONSTRAINT NAME:  fb_foo_bar_excl

编辑:虽然这有效但我同意康拉德·弗里克斯的评论,规范化你的桌子可能是一个更好的主意。