0

SQLについて学び始めたばかりで、理解できない質問がありました。

次のテーブルとその主キーに基づいた設定があります。テーブル間で同じ名前の列は外部キーによって制約されています。

会社:

  • CompanyId

分割:

  • CompanyId
  • DivisionId

リソース:

  • CompanyId
  • ResourceId

DivisionResource:

  • CompanyId
  • DivisionId
  • ResourceId
  • DivisionResourceは、部門とリソースの間に多対多の関係を作成し、それらを制約して、部門が同じ会社のリソースにのみリンクできるようにするために使用されます。
  • DivisionResourceがなければ、DivisionとResourceは、一意のレコードを含めるための主キーとしてCompanyIdを必要としません。

だから私の質問はこれです:DivisionResourceが主キーに余分な列を持たせることなくDivisionResourceが作成するのと同様の制約を作成する方法はありますか?

4

3 に答える 3

1

以下のスキーマのResourceCompanyとDivisionCompanyは接続テーブルです。主キーにはCompanyIdが含まれますが、ResourceとDivisionには1つの列を持つ主キーが含まれます。これはあなたが探していたものです。

リソース->ResourceCompany

DivisionResource-> ResourceCompany

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

DivisionResourceの挿入と更新時にINSTEADOFトリガーを作成します

トリガーは、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'にFOREIGNKEY制約を導入すると、サイクルまたは複数のカスケードパスが発生する可能性があります。ON DELETENOACTIONまたはONUPDATENO ACTIONを指定するか、他のFOREIGNKEY制約を変更します。

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))
于 2013-01-18T03:17:06.653 に答える