web-dev-qa-db-ja.com

複数の列を主キー(複合主キー)として使用する理由

この例は w3schoolsから です。

CREATE TABLE Persons
(
    P_Id int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255),
    CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)

私の理解では、両方の列(P_IdLastName)が一緒になって、テーブルPersonsの主キーを表します。これは正しいです?

  • なぜ誰かが単一の列ではなく複数の列を主キーとして使用したいのですか?
  • 特定のテーブルで主キーとして一緒に使用できる列の数は?
100
rockbala

あなたの理解は正しいです。

多くの場合、これを行います。 1つの例は、OrderHeaderOrderDetailのような関係です。 OrderHeaderのPKはOrderNumberである可能性があります。 OrderDetailのPKは、OrderNumberおよびLineNumberになります。これらのいずれかである場合、一意ではありませんが、2つの組み合わせは一意であることが保証されます。

別の方法は、生成された(非インテリジェント)主キーを使用することです。たとえば、この場合はOrderDetailIdです。しかし、その関係は必ずしも簡単に見えるとは限りません。一部の人々は、1つの方法を好みます。他の方法を好む人もいます。

111
MJB

複合主キーの別の例は、関連テーブルの使用法です。一連の人々を含む個人テーブルと、一連のグループを含むグループテーブルがあるとします。次に、個人とグループで多対多の関係を作成します。各人が多くのグループに属することを意味します。複合主キーを使用すると、テーブル構造は次のようになります。

Create Table Person(
PersonID int Not Null,
FirstName varchar(50),
LastName varchar(50),
Constraint PK_Person PRIMARY KEY (PersonID))

Create Table Group (
GroupId int Not Null,
GroupName varchar(50),
Constraint PK_Group PRIMARY KEY (GroupId))

Create Table GroupMember (
GroupId int Not Null,
PersonId int Not Null,
CONSTRAINT FK_GroupMember_Group FOREIGN KEY (GroupId) References Group(GroupId),
CONSTRAINT FK_GroupMember_Person FOREIGN KEY (PersonId) References Person(PersonId),
CONSTRAINT PK_GroupMember PRIMARY KEY (GroupId, PersonID))
24
John Hartsock

W3Schoolsの例では、いつ複合主キーを使用する必要があるかは示されておらず、他のキーと同じサンプルテーブルを使用した構文例のみが提供されています。

それらの例の選択は、無意味なキー(P_Id)と自然なキー(LastName)を組み合わせることにより、おそらく誤解を招く可能性があります。主キーのこの奇妙な選択は、スキーマに従って次の行が有効であり、学生を一意に識別するために必要であることを示しています。直感的にはこれは意味がありません。

1234     Jobs
1234     Gates

さらに読む: 偉大な主キーの議論 または単にGoogle meaningless primary keysまたはこれを熟読する SOの質問

FWIW-私の2セントは、複数列の主キーを避け、単一の生成されたidフィールド(代理キー)を主キーとして使用し、必要に応じて追加の(一意の)制約を追加することです。

9
Robert Paulson

複数の属性の組み合わせの一意性を確保したい場合は常に、複合キー(複数の属性を持つキー)を使用します。単一の属性キーは同じことを達成しません。

3
nvogel

はい、両方とも主キーを形成します。特に 代理キー を持たないテーブルでは、各レコードの一意の識別子として複数の属性を指定する必要がある場合があります(悪い例:名と姓の両方を持つテーブルは、それらの組み合わせは一意である必要があります)。

2
ig0774

一般に、キー内の複数の列は、代理キーよりもパフォーマンスが低下します。代理キーを使用してから、複数列キーに一意のインデックスを作成することを好みます。これにより、パフォーマンスが向上し、必要な一意性が維持されます。さらに良いことに、そのキーの値の1つが変更されても、215個の子テーブルの100万個の子エントリを更新する必要はありません。

2
HLGEM

二番目の質問

特定のテーブルで主キーとして一緒に使用できる列の数は?

実装固有です。使用される実際のDBMSで定義されます。[1]、[2]、[3] 使用するデータベースシステムの技術仕様を調べる必要があります。非常に詳細なものもあれば、そうでないものもあります。用語が異なるため、このような制限についてウェブを検索するのは難しい場合があります。用語複合主キーは必須です;)

明示的な情報が見つからない場合は、テストデータベースを作成して、制限違反(予想される)の安定した(および特定の)処理を期待できることを確認してください。これについて正しい情報を取得するように注意してください。場合によっては制限が蓄積され、異なるデータベースレイアウトで異なる結果が表示されることがあります。


2
Wolf

リレーショナルデータベースで中間テーブルを使用している場合、複数のテーブルで主キーを使用すると便利です。

例のためにかつて作成したデータベース、特にそのテーブル内の3つのテーブルを使用します。数年前にウェブコミック用のデータベースを作成しました。 1つのテーブルは「コミック」と呼ばれました。すべてのコミック、そのタイトル、画像ファイル名などのリストです。主キーは「comicnum」でした。

2番目のテーブルは「キャラクター」、つまり名前と簡単な説明でした。主キーは「charname」にありました。

いくつかの例外を除いて、各コミックには複数のキャラクターがあり、各キャラクターは複数のコミック内に登場するため、それを反映するために「キャラクター」または「コミック」のいずれかに列を入れることは非現実的でした。代わりに、私は 三番 テーブルは「comicchars」と呼ばれ、それはどのキャラクターがどのコミックに登場したかのリストでした。このテーブルは基本的に2つのテーブルを結合しているため、charnameとcomicnumの2つのカラムが必要であり、主キーは両方にありました。

1
Mr. Initial Man

複合主キーを作成して、単一のレコードを構成する一意性列値を保証します。これは、複製されるべきではないデータの挿入を防ぐのに役立つ制約です。

つまり、すべての学生IDと出生証明書番号が一意に1人に割り当てられている場合。次に、人の主キーを学生IDと出生証明書番号の組み合わせにすることをお勧めします。これは、異なる学生IDと同じ出生証明書を持つ2人を誤って挿入することを防ぐためです。

0
kiwicomb123