Postgresql postgres多对一唯一约束
我很好奇是否有一种方法可以编写一个惟一的约束来支持以下情况 假设表1中有一个用户的事实,共有四列: 用户id:用户的唯一id 资料来源:细节来自哪里 d1:事实的维度1 d2:事实的维度2 以下是此表中的数据示例:Postgresql postgres多对一唯一约束,postgresql,unique-constraint,Postgresql,Unique Constraint,我很好奇是否有一种方法可以编写一个惟一的约束来支持以下情况 假设表1中有一个用户的事实,共有四列: 用户id:用户的唯一id 资料来源:细节来自哪里 d1:事实的维度1 d2:事实的维度2 以下是此表中的数据示例: | row_id | user_id | source | d1 | d2 | |--------|---------|--------|--------|---------| | 1 | aaa111 | foo | bar | 123
| row_id | user_id | source | d1 | d2 |
|--------|---------|--------|--------|---------|
| 1 | aaa111 | foo | bar | 123 |
| 2 | aaa111 | foo | baz | 'horse' |
| 3 | aaa111 | scrog | bar | 123 |
| 4 | bbb222 | foo | goober | 456 |
目前,source+d1+d2上存在唯一约束。这很好,因为它允许同一用户拥有d1、d2的副本,只要它们具有不同的源。
第1行和第3行为用户aaa111演示了这一点
但是,此约束不会阻止添加以下行
| row_id | user_id | source | d1 | d2 |
|--------|---------|--------|--------|---------|
| 1 | aaa111 | foo | bar | 123 |
| 2 | aaa111 | foo | baz | 'horse' |
| 3 | aaa111 | scrog | bar | 123 |
| 4 | bbb222 | foo | goober | 456 |
| 5 | bbb222 | turnip | baz | 'horse' | <---- allowed new row
…因为第2行和第5行的源不同
我想添加一个唯一的约束,其中d1和d2的组合可能只存在于单个用户id中
换句话说,单个用户可以根据需要拥有任意多个唯一源、d1、d2组合,但不能与其他用户共享d1、d2
这种数据模型在支持这种约束方面是否存在根本缺陷?或者是否有一个独特的约束可以帮助实施这一点?提前感谢您的建议。这是一个条件约束,您可以在插入或更新之前使用触发器,在违反约束时引发异常:
CREATE OR REPLACE FUNCTION check_user_combination() RETURNS trigger AS
$$
DECLARE
vCheckUser INTEGER;
BEGIN
SELECT INTO vCheckUser user_id
FROM table1
WHERE d1 = NEW.d1
AND d2 = NEW.d2
AND user_id <> NEW.user_id;
IF vCheckUser IS NOT NULL THEN
RAISE EXCEPTION 'User % have already d1=% and d2=%',vCheckUser,NEW.d1, NEW.d2;
END IF;
RETURN NEW;
END;
$$
language 'plpgsql';
CREATE TRIGGER tr_check_combination BEFORE INSERT OR UPDATE ON table1 FOR EACH ROW EXECUTE PROCEDURE check_user_combination();
这将防止为相同的d1和d2插入或更新其他用户。绝对完美。非常感谢!