[英]Enforce subset relationship in postgres
如何在不使用應用程序代碼的情況下在我的數據庫模式中強制執行以下業務邏輯:
這是我到目前為止所擁有的:
create table companies (
id serial primary key,
name varchar not null,
unique(name)
);
create table vehicles (
id serial primary key,
name varchar not null,
unique(name)
);
create table users (
id serial primary key,
company_id integer not null,
name varchar not null,
foreign key (company_id) references companies(id)
);
create table vehicle_companies (
id serial primary key,
vehicle_id integer not null,
company_id integer not null,
foreign key (vehicle_id) references vehicles(id),
foreign key (company_id) references companies(id)
);
create table user_vehicles (
user_id integer not null,
vehicle_company_id integer not null,
foreign key (user_id) references users(id),
foreign key (vehicle_company_id) references vehicle_companies(id)
);
我怎樣才能確保user_vehicles
表中的行始終只引用具有company_id
的vehicle_companies
記錄,這與其引用的users
表記錄的company_id
相同?
我正在使用 postgres。
您正在嘗試跨獨立實體(表)實施參照完整性。 你不能用簡單的約束來做到這一點(也許是排除約束——但我不這么認為)。 為此,您需要在user_vehicles
上觸發。
create or replace function validate_user_vehicle_company()
returns trigger
language plpgsql
as $$
begin
if not exists( select null
from users u
join vehicle_companies v
on ( v.company_id = u.company_id)
where u.id = new.user_id
and v.company_id = new.vehicle_company_id
and v.vehicle_id = new.vehicle_company_id
)
then
raise exception E'During % on %.%\nUser.company_id does not match vehicle_companies.company_id' ,tg_op,tg_table_schema,tg_table_name;
end if;
return new;
end;
$$;
create or replace trigger user_vehicles_biur
before insert or update
on user_vehicles
for each row
execute function validate_user_vehicle_company();
我在這里整理了一個簡短的演示,其中包含非常簡單的數據值。
這個模式為我解決了它:
create table companies (
id serial primary key,
name varchar not null,
unique(name)
);
create table vehicles (
id serial primary key,
name varchar not null,
unique(name)
);
create table users (
id serial primary key,
company_id integer not null,
name varchar not null,
unique (id, company_id),
foreign key (company_id) references companies(id)
);
create table vehicle_companies (
id serial primary key,
vehicle_id integer not null,
company_id integer not null,
unique (vehicle_id, company_id),
foreign key (vehicle_id) references vehicles(id),
foreign key (company_id) references companies(id)
);
create table user_vehicles (
id serial primary key,
user_id integer not null,
vehicle_id integer not null,
company_id integer not null,
unique (id),
unique (vehicle_id, company_id),
foreign key (user_id, company_id) references users(id, company_id),
foreign key (vehicle_id, company_id) references vehicle_companies(vehicle_id, company_id)
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.