刚刚开始学习SQL并且有一个我无法弄清楚的问题。
我有一个基于以下表及其主键的设置,表之间具有相同名称的列受外键约束:
公司:
- CompanyId
司:
- CompanyId
- DivisionId
资源:
- CompanyId
- RESOURCEID
DivisionResource:
- CompanyId
- DivisionId
- RESOURCEID
所以我的问题是:有没有办法在DivisionResource创建时创建一个类似的约束而不强制Division和Resource在其主键中有一个额外的列?
答案 0 :(得分:1)
下面架构中的ResourceCompany和DivisionCompany是连接表。他们的主键中将包含CompanyId,但Resource和Division将具有一列的主键。这就是你要找的东西。
资源 - > ResourceCompany
DivisionResource - > ResourceCompany
分部 - > DivisionCompany
DivisionResource - > DivisionCompany
create table Company (CompanyId int primary key);
create table DivisionCompany (
CompanyId int foreign key references Company(CompanyId),
DivisionId int,
constraint pk_div_company primary key (DivisionId, CompanyId)
);
create table Division (
DivisionId int primary key,
CompanyId int,
constraint fk_div_company foreign key (DivisionId, CompanyId) references DivisionCompany(DivisionId, CompanyId));
create table ResourceCompany (
CompanyId int foreign key references Company(CompanyId),
ResourceId int,
constraint pk_res primary key (ResourceId, CompanyId));
create table Resource(
ResourceId int primary key,
CompanyId int,
constraint fk_res_company foreign key (ResourceId, CompanyId) references ResourceCompany(ResourceId, CompanyId)
);
create table DivisionResource(
CompanyId int,
DivisionId int,
ResourceId int,
constraint pk_DivRes primary key (DivisionId, ResourceId),
constraint fk_DivCompany foreign key (DivisionId, CompanyId) references DivisionCompany(DivisionId, CompanyId),
constraint fk_ResCompany foreign key (ResourceId, CompanyId) references ResourceCompany(ResourceId, CompanyId)
);
答案 1 :(得分:0)
在插入和更新DivisionResource
时创建INSTEAD OF触发器触发器将检查Divistion和Resource是否拥有相同的公司。如果他们不这样做,它将无法修改
或者,使用修改DivisionResource的存储过程会更好。然后触发器需要调用它。
答案 2 :(得分:0)
我假设您正在尝试创建以下架构:
CREATE TABLE company (
companyId int PRIMARY KEY)
CREATE TABLE division (
divisionId int PRIMARY KEY,
companyId int
REFERENCES company (companyId) ON DELETE CASCADE ON UPDATE CASCADE)
CREATE TABLE resource (
resourceId int PRIMARY KEY,
companyId int
REFERENCES company (companyId) ON DELETE CASCADE ON UPDATE CASCADE)
CREATE TABLE divisionResource (
divisionId int
REFERENCES division (divisionId) ON DELETE CASCADE ON UPDATE CASCADE,
resourceId int
REFERENCES resource (resourceId) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (divisionId, resourceId))
引发:
Introducing FOREIGN KEY constraint on table 'divisionResource' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
将divisionId
或resourceId
更改为ON DELETE NO ACTION ON UPDATE NO ACTION
基本上会破坏参照完整性。我在评论中建议的是制作代理密钥。但是,如果为resource
创建单独的表格会更好。这将保持参照完整性并规范化架构:
CREATE TABLE company (
companyId int PRIMARY KEY)
CREATE TABLE division (
divisionId int PRIMARY KEY,
companyId int
REFERENCES company (companyId) ON DELETE CASCADE ON UPDATE CASCADE)
CREATE TABLE resource (
resourceId int PRIMARY KEY)
CREATE TABLE companyResource (
resourceId int
REFERENCES resource (resourceId) ON DELETE CASCADE ON UPDATE CASCADE,
companyId int
REFERENCES company (companyId) ON DELETE CASCADE ON UPDATE CASCADE)
CREATE TABLE divisionResource (
divisionId int
REFERENCES division (divisionId) ON DELETE CASCADE ON UPDATE CASCADE,
resourceId int
REFERENCES resource (resourceId) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (divisionId, resourceId))