6

假设我有以下表格

CREATE TABLE plugins (
id int primary key,
type text);

insert into plugins values (1,'matrix');
insert into plugins values (2,'matrix');
insert into plugins values (3,'function');
insert into plugins values (4,'function');

CREATE TABLE matrix_params (
id int primary key,
pluginid int references plugins (id)
);

这一切都按预期工作,但我想添加一个额外的约束,matrix_param 只能引用类型为“matrix”的 pluginid。所以

insert into matrix_params values (1,1);

应该成功但是

insert into matrix_params values (2,3);

应该失败。

matrix_params 的简单约束不起作用,因为它无法知道 plugins 表中的相应类型是什么。

4

3 回答 3

4

您可以为此使用 CHECK 约束。您不能将查询放在 CHECK 约束中,但可以调用函数;因此,我们构建了一个简单的函数来告诉我们 apluginid是否为矩阵:

create or replace function is_matrix(int) returns boolean as $$
    select exists (
        select 1
        from plugins
        where id   = $1
          and type = 'matrix'
    );
$$ language sql;

并将其包装在 CHECK 约束中:

alter table matrix_params add constraint chk_is_matrix check (is_matrix(pluginid));

然后:

=> insert into matrix_params values (1,1);
=> insert into matrix_params values (2,3);
ERROR:  new row for relation "matrix_params" violates check constraint "chk_is_matrix"

FK 负责参照完整性和级联。

于 2012-04-13T06:05:22.610 回答
2

在引用表中使用复合键,在引用表中使用CHECK约束,例如

CREATE TABLE plugins (
id int primary key,
type text, 
UNIQUE (type, id)
);

CREATE TABLE matrix_params (
id int primary key,
plugintype text DEFAULT 'matrix' NOT NULL
   CHECK (plugintype = 'matrix'),
pluginid int NOT NULL,
FOREIGN KEY (plugintype, pluginid)
   references plugins (type, id)
);
于 2012-04-13T08:21:34.537 回答
0

处理此问题的一种方法是使用可序列化事务。

http://wiki.postgresql.org/wiki/SSI#FK-Like_Constraints

于 2012-04-13T12:32:24.593 回答