web-dev-qa-db-ja.com

複合主キーかどうか?

これが私を混乱させているものです。私はデータベーステーブルに複合主キーを持っていることがよくあります。このアプローチの悪い面は、エントリを削除または編集するときにかなり余分な作業が必要になることです。しかし、このアプローチはデータベース設計の精神に基づいていると思います。

反対側には、複合キーを使用せず、テーブルに別の「id」列を導入する友人がいます。他のすべてのキーは単なるFKです。削除および編集手順のコーディング中の作業ははるかに少なくなります。ただし、データエントリの一意性をどのように維持するかはわかりません。

例えば:
方法1

create table ProxUsingDept (
    fkProx int references Prox(ProxID) NOT NULL,    
    fkDept int references Department(DeptID) NOT NULL,    
    Value int,    
    PRIMARY KEY(fkProx,fkDept)
)

方法2

create table ProxUsingDept (
        ID int NOT NULL IDENTITY PRIMARY KEY
        fkProx int references Prox(ProxID) NOT NULL,    
        fkDept int references Department(DeptID) NOT NULL,    
        Value int
)

どちらが良いですか? 2番目のアプローチを使用することの悪い面は何ですか?助言がありますか?

18
sandalone

私は個人的にprefer 2番目のアプローチ(そしてほぼ100%の確率でそれを使用します)-代理IDフィールドを導入します。

どうして?

  • テーブルを参照するテーブルの作業がはるかに楽になります-JOIN条件ははるかに単純です単一のID列(2、3、または結合する必要のあるさらに多くの列ではなく、すべて)時間)

  • テーブルを参照するテーブルは、外部キーフィールドとして単一のIDを保持するだけでよく、複合キーの複数の列を保持する必要がないため、作業が大幅に楽になります。

  • データベースが一意のID列の作成を処理できるため(INT IDENTITYを使用)、作業が大幅に楽になります。

ただし、データエントリの一意性をどのように維持するかはわかりません。

非常に簡単です。主キーとして使用する複合列にUNIQUEINDEXを配置してください。

CREATE UNIQUE INDEX UIX_WhateverNameYouWant 
   ON dbo.ProxUsingDept(fkProx, fkDept)

これで、テーブルに(fkProx, fkDept)のペアが重複しないことが保証されます-問題は解決しました!

26
marc_s

次の質問をします。

ただし、データエントリの一意性をどのように維持するかはわかりません。

一意性を維持するには、本来の主キーを形成する列に個別の複合UNIQUEインデックスを宣言します。

どちらが良いですか?

人によって意見は異なり、時には強く抱かれます。より多くの人が代理整数キーを使用していることがわかると思います(それが「正しい」解決策になるわけではありません)。

2番目のアプローチを使用することの悪い面は何ですか?

代理キーを使用することの欠点のいくつかを次に示します。

  1. 自然主キーの一意性を維持するには、追加のインデックスが必要です。

  2. 必要な結果を得るためにデータを選択するときに、追加のJOINが必要になる場合があります(これは、複合自然キーの列のみを使用してクエリの要件を満たすことができる場合に発生します。この場合、JOINingではなく外部キー列を使用できます。元のテーブルに戻ります)。

17
Larry Lustig

M:N結合テーブルのように、複合キーが最も理にかなっている場合があります(そして、性質またはM:Nリンクが変更された場合は、とにかくこのテーブルを作り直す必要があります)。

0
9000