web-dev-qa-db-ja.com

継承されたテーブルに新しい代理キーが必要ですか、それとも親テーブルのキーを使用する必要がありますか?

私は "is a"関係(別名継承)を使用していくつかのモデルを作成していますが、継承されたテーブルの主キーと親テーブルを指す外部キーに関して、2つの方法があります。

  • 戦略#1は、継承された各テーブルに常に新しいサロゲートキーを作成し、親テーブルの主キーへの参照を別の列に格納することです(1対1のマッピングを確実にするために、その列に一意の制約を設定します)。

  • 戦略#2は、継承されたテーブルの主キー値を親テーブルの主キーと同じ値にすることでした。

ここには明確な勝者がいると思います(戦略#2)が、見逃していない潜在的な問題がないことを確認したいと思います。

以下は、各戦略を詳細に記述したコード(SQL Serverを対象としていますが、汎用的なもの)です。

------Strategy #1: always create a surrogate key for a child table (separate column holds parent table's primary key)----------
drop table if exists TruckAsset
drop table if exists VehicleAsset
drop table if exists Asset

create table Asset
(
    AssetId int not null,
    primary key (AssetId)
)

create table VehicleAsset
(
    VehicleAssetId int not null, /*surrogate key*/
    AssetId int not null,   
    VehicleRegistrationExpirationDate date not null, /*specialization of Asset*/

    primary key (VehicleAssetId),
    constraint UQ_AssetId unique (AssetId),
    foreign key (AssetId) references Asset(AssetId)
)

create table TruckAsset
(
    TruckAssetId int not null, /*surrogate key*/
    VehicleAssetId int not null,
    CargoCapacityCubicMeters float not null, /*specialization of VehicleAsset*/

    primary key (TruckAssetId),
    constraint UQ_VehicleAssetId unique (VehicleAssetId),
    foreign key (VehicleAssetId) references VehicleAsset(VehicleAssetId)
)

INSERT INTO Asset(AssetId)VALUES(1234)
INSERT INTO VehicleAsset(VehicleAssetId, AssetId, VehicleRegistrationExpirationDate) VALUES (5678, 1234, '2020-01-01')
INSERT INTO TruckAsset(TruckAssetId, VehicleAssetId, CargoCapacityCubicMeters) VALUES (9999, 5678, 8.80977)

GO

これに対して

------Strategy #2: primary key references parent table's primary key directly----------
drop table if exists TruckAsset
drop table if exists VehicleAsset
drop table if exists Asset

create table Asset
(
    AssetId int not null,
    primary key (AssetId)
)

create table VehicleAsset
(
    VehicleAssetId int not null,
    VehicleRegistrationExpirationDate date not null, /*specialization of Asset*/

    primary key (VehicleAssetId),
    foreign key (VehicleAssetId) references Asset(AssetId)
)

create table TruckAsset
(
    TruckAssetId int not null,
    CargoCapacityCubicMeters float not null, /*specialization of VehicleAsset*/

    primary key (TruckAssetId),
    foreign key (TruckAssetId) references VehicleAsset(VehicleAssetId)
)

INSERT INTO Asset(AssetId)VALUES(1234)
INSERT INTO VehicleAsset(VehicleAssetId, VehicleRegistrationExpirationDate) VALUES (1234, '2020-01-01')
INSERT INTO TruckAsset(TruckAssetId, CargoCapacityCubicMeters) VALUES (1234, 8.80977)
----------------------------------------
1
Anssssss

戦略#2には名前があります。これは共有主キーと呼ばれます。広く使用されているのは型の関係です。 Stackoverflowには、この概念に関連する質問をグループ化するタグオーバーがあります。

リンクを参照

1
Walter Mitty