0

刚开始学习 SQL,有一个我想不通的问题。

我有一个基于下表及其主键的设置,表之间具有相同名称的列受外键约束:

公司:

  • 公司编号

分配:

  • 公司编号
  • 部门 ID

资源:

  • 公司编号
  • 资源 ID

部门资源:

  • 公司编号
  • 部门 ID
  • 资源 ID
  • DivisionResource 用于在部门和资源之间创建多对多关系并对其进行约束,以便部门只能链接到同一公司的资源。
  • 如果没有 DivisionResource,Division 和 Resource 就不需要 CompanyId 作为包含唯一记录的主键。

所以我的问题是:有没有办法创建与 DivisionResource 创建类似的约束,而不强制 Division 和 Resource 在其主键中有一个额外的列?

4

3 回答 3

1

下面架构中的 ResourceCompany 和 DivisionCompany 是连接表。他们的主键中将包含 CompanyId,但 Resource 和 Division 将具有一列的主键。这就是你要找的。

资源 -> 资源公司

部门资源 -> 资源公司

部门 -> 部门公司

部门资源 -> 部门公司

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)
    );
于 2013-01-18T04:16:08.223 回答
0

在 DivisionResource 的插入和更新上创建 INSTEAD OF 触发器

触发器将检查 Divistion 和 Resource 是否属于同一公司。如果他们不这样做,它将导致修改失败

或者,最好有一个修改 DivisionResource 的存储过程。然后触发器需要调用它。

于 2013-01-18T03:06:54.633 回答
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))

哪个抛出:

在表 'divisionResource' 上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

更改其中一个divisionIdresourceId更改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))
于 2013-01-18T03:17:06.653 回答