2011-09-12 11 views
0

複合プライマリキーテーブル(メンテナンスアイテム)があります。このテーブル内のアイテム間の親子関係をマップする別のテーブルを作成したいと思います。コンポジットプライマリキーテーブルの親子関係のマッピング

私は、親子関係テーブルは、いずれかのオプション1またはオプション2

NOTE下記参照作成する方法を確認していない:私たちのビジネスルールは、親子関係ができるだけ共有するメンテナンス項目の間で出ていることを明記します同じ保守プログラムこれは決して変化しません!

テーブルメンテナンスプログラム
プログラムコード(主キー)
ProgramDescription
他のコラム...

表のメンテナンス項目(複合主キー表)
プログラムコード(複合主キー)
メンテナンスコード(複合主キー)
メンテナンス説明
他のコラム...

表親/子メンテナンス項目(オプション1)
プログラムコード
ParentMaintenanceCode
ChildMaintenanceCode

表親/子メンテナンス項目(オプション2)
ParentProgramCode(ChildProgramCodeと同じ値)
親メンテナンスコード
ChildProgramCode(ParentProgramCodeと同じ値)
ChildMaintenanceCode

それが関係マッピングテーブルだけで親/子テーブル内の他の列はありません。

どちらが最適ですか?オプション2はベストプラクティスに適していると思われますが、私たちのビジネスルールを考慮すると、まったく同じデータ(ProgramCode)を持つ2つの列が基本的にあることを意味します。

答えて

2

メンテナンスアイテム間に多対多の関係が必要な場合は、連想エンティティを使用する唯一の理由は示唆していることです。それがあなたの後ろであれば、オプション1があなたのやり方です。スキーマは

create table MaintenanceProgram 
(
    ProgramCode int not null , 

    ... -- other non-key attributes here 

    primary key (ProgramCode) , 

) 
create table MaintenanceItem 
(
    ProgramCode  int not null , 
    MaintenanceCode int not null , 

    ... -- other non-key attributes here 

    primary key (ProgramCode , MaintenanceCode) , 

    foreign key      (ProgramCode) 
    references MaintenanceProgram (ProgramCode) , 

) 
create table MaintenanceItemMap 
(
    ProgramCode   int not null , 
    ParentMaintenanceCode int not null , 
    ChildMaintenanceCode int not null , 

    primary key (ProgramCode , ParentMaintenanceCode , ChildMaintenanceCode) , 

    foreign key     (ProgramCode , ParentMaintenanceCode) 
    references MaintenanceItem (ProgramCode , MaintenanceCode  ) , 
    foreign key     (ProgramCode , ChildMaintenanceCode ) 
    references MaintenanceItem (ProgramCode , MaintenanceCode  ) , 

    check (ParentMaintenanceCode != ChildMaintenanceCode) , 

) 

これは、関連するすべてのメンテナンス項目は、同じプログラムコードを共有していることを確認し、メンテナンス項目が自身に(チェック制約)をマッピングすることができないというようなもののようになります。

しかし、あなたの問題ステートメントは、親子関係を参照しています。これは、階層/ツリーのように聞こえます。この場合は、あなたが望むのスキーマは次のようになります:

create table MaintenanceProgram 
(
    ProgramCode int not null , 

    ... -- other non-key attributes here 

    primary key (ProgramCode) , 

) 
create table MaintenanceItem 
(
    ProgramCode   int not null , 
    MaintenanceCode  int not null , 
    ParentMaintenanceCode int  null , 

    ... -- other non-key attributes here 

    primary key (ProgramCode , MaintenanceCode) , 

    foreign key      (ProgramCode ) 
    references MaintenanceProgram ( ProgramCode) , 
    foreign key      (ProgramCode , ParentMaintenanceCode) 
    references MaintenanceItem (ProgramCode , MaintenanceCode  ) , 

    check (MaintenanceCode != ParentMaintenanceCode or ParentMaintenanceCode is null) , 

) 

を上記各メンテナンス項目は、単一のメンテナンスプログラムに関連していることを述べています。逆に、各メンテナンスプログラムにはゼロ個以上のメンテナンス項目があります。

さらに、各メンテナンス項目にはゼロまたは1つの親メンテナンス項目があり、これは同じメンテナンスプログラムに関連している必要があります。

チェック制約は、特定のメンテナンス項目がそれ自身の親ではない可能性があることを示します。

+0

あなたのトップスキーマは、私が後にしたものです。多対多の関係にする必要があります。ありがとうございました! – Reafidy

1

なぜオプション2がベストプラクティスだと思いますか?それらが同じでなければならない場合、それらを異なる列に入れるのは意味がありません。オプション1は2より優れています。

+0

これは私の未学習の思考でした。 – Reafidy

1

オプション1が最善の答えです。あなたはその子を親に参照することができます(参照整合性を強制します)。また、SQL Server 2005以降を使用している場合は、再帰CTEを使用して、メニュー、ドロップダウンなどのために親/子の階層を構築することができます。

+0

Wilさん、再帰的なCTEがおそらく私の次のハードルになるでしょう。 – Reafidy