我在PostgreSQL数据库中有四个表:
基本上:
我想知道数据库是否有办法约束UserLocations关联表中的条目,以使引用的用户和位置必须具有相同的company_id值。我不希望公司A的用户拥有公司B的位置。
我可以在我的应用程序层(rails)检查这个,但如果选项存在,我会有兴趣将其作为硬数据库级别约束。
答案 0 :(得分:2)
您可以通过外键引用和冗余来实现此目的。
因此,UserLocations
表格会有UserId
,LocationId
和CompanyId
。然后它将具有以下外键关系:
foreign key (UserId, CompanyId) references Users(UserId, CompanyId)
foreign key (LocationId, CompanyId) references Locations(LocationId, CompanyId)
当然,您必须将Users(UserId, CompanyId)
和Locations(LocationId, CompanyId)
声明为引用的唯一键。这有点多余,但它确保与公司匹配而不创建触发器。
答案 1 :(得分:1)
重叠外键约束是你的朋友。
create table company (
company_id integer primary key
);
-- Reserved words include "user". Better to use identifiers that
-- are not reserved words.
create table "user" (
user_id integer primary key,
company_id integer not null references company (company_id),
-- Unique constraint lets this be the target of a foreign key reference.
unique (user_id, company_id)
);
create table location (
location_id integer primary key,
company_id integer not null references company (company_id),
unique (location_id, company_id)
);
create table user_location (
user_id integer not null,
location_id integer not null,
company_id integer not null,
-- Not sure what your primary key is here.
-- These foreign keys overlap on the column "company_id", so there
-- can be only one value for it.
foreign key (user_id, company_id) references "user" (user_id, company_id),
foreign key (location_id, company_id) references location (location_id, company_id)
);