我能想到的唯一方法是在
users
表上添加一个对
(id, superuser)
的唯一约束,并通过“复制”
superuser
标志在
user_has_job
表中引用它。
create table users (
id serial primary key,
name text not null,
superuser boolean not null default false
);
alter table users add constraint uc_users unique (id, superuser);
create table job (
id serial primary key,
description text
);
create table user_has_job (
user_id integer references users (id),
superuser boolean not null default true check (superuser),
job_id integer references job(id),
constraint user_has_job_pk PRIMARY KEY (user_id, job_id),
foreign key (user_id, superuser) references users (id, superuser)
);
insert into users
(id, name, superuser)
values
(1, 'arthur', false),
(2, 'ford', true);
insert into job
(id, description)
values
(1, 'foo'),
(2, 'bar');
由于default
值,当插入user_has_job
表时不需要指定superuser
列。因此,以下插入操作可以正常工作:
insert into user_has_job
(user_id, job_id)
values
(2, 1);
但是尝试将Arthur插入表中失败了:
insert into user_has_job
(user_id, job_id)
values
(1, 1);
这也可以防止将ford转变为非超级用户。以下是更新内容:
update users
set superuser = false
where id = 2
出现错误,错误信息如下:
ERROR: 在表 "users" 上执行更新或删除操作违反了表 "user_has_job" 中的外键约束"user_has_job_user_id_fkey1"。
详情:键 (id, superuser)=(2, t) 仍被表 "user_has_job" 引用。
superuser=True
。否则它不会保存新的数据行。 - microo8