web-dev-qa-db-ja.com

複合主キーを正しく作成する方法 - MYSQL

これは私が働いている強烈な設定の総体的な過度の単純化です。 table_1table_2はどちらもIDとして自動インクリメントの代理主キーを持っています。 infoは、table_1table_2の両方に関する情報を含むテーブルです。

table_1 (id, field)  
table_2 (id, field, field)
info ( ???, field)

infoの主キーをtable_1table_2のIDの合成にするかどうかを決定しようとしています。私がこれをやるとしたら、これらのどれが最も理にかなっていますか?
(この例ではID 11209とID 437を組み合わせています)

INT(9) 11209437 (これがなぜ悪いのか想像できる)
VARCHAR (10) 11209-437
DECIMAL (10,4) 11209.437

または、他の何か?

これをMYSQL MYISAM DBの主キーとして使用しても問題ありませんか。

160
filip

複合(複数列)キーを使用します。

CREATE TABLE INFO (
    t1ID INT,
    t2ID INT,
    PRIMARY KEY (t1ID, t2ID)
) 

こうすることで、それぞれのテーブルを指す外部キーとしてt1IDとt2IDを持つことができます。

300
AlexCuse

"info"テーブルの主キーを他のテーブルの2つの値の合成にしないでください。

他の人はその理由をより明確に説明することができますが、2つの情報で実際に構成されている列を持つのは間違っていると感じます。何らかの理由で2番目のテーブルのIDをソートしたい場合はどうしますか?どちらかのテーブルの値が存在する回数を数えたい場合はどうしますか?

私は常にこれらを2つの異なる列として保持します。 mysqlで2列の主キーを使用することができます... PRIMARY KEY(id_a、id_b)...しかし、2列の一意のインデックスを使用し、自動インクリメントの主キーフィールドを持つことをお勧めします。

20
wmorse

構文はCONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)です。例えば::

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

上記の例は、あなたがテーブルを作成している間にそれを書いているなら、うまくいくでしょう。例えば:

CREATE TABLE person (
   P_Id int ,
   ............,
   ............,
   CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);

この制約を既存のテーブルに追加するには、次の構文に従う必要があります。

ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)
14

すでにテーブルを作成しているとします。このクエリを使用して複合主キーを作成できます。

alter table employee add primary key(emp_id,emp_name);
4
Usman Yaqoob

複合主キーは、ファクト表との多対多の関係を作りたい場合に必要なものです。たとえば、いくつかのプロパティを含むホリデーレンタルパッケージがあるとします。一方で、この物件は、単独で、または他の物件と共に、いくつかのレンタルパッケージの一部として利用することもできます。このシナリオでは、資産/パッケージファクトテーブルを使用して、資産と賃貸パッケージの間の関係を確立します。プロパティとパッケージの間の関連付けは一意になります。property_idをプロパティテーブルと組み合わせて、またはpackage_idをパッケージテーブルと組み合わせて結合することになります。それぞれの関係は一意であり、auto_incrementキーは他のテーブルでは機能しないため冗長です。したがって、複合キーを定義することが答えです。

4
Adam Penny

個人的なデザインの好み以外にも、複合主キーを使用したい場合があります。テーブルには、一意の組み合わせを提供する2つ以上のフィールドがありますが、必ずしも外部キーによるものではありません。

一例として、米国の各州には、独自の議会地区があります。多くの州が個別にCD-5を所有している場合がありますが、50州のうちのどの州にも複数のCD-5が存在することは決してありません。したがって、マサチューセッツ州CD-5の自動番号フィールドを作成するのは冗長です。

データベースが動的なWebページを操作する場合、2フィールドの組み合わせでクエリするコードを書くのは、自動番号キーを抽出/再送信するよりもはるかに簡単です。

それで私は最初の質問に答えていない間、私は確かにアダムの直接の答えに感謝します。

3
KiloVoltaire
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);
1
Master Mind

@AlexCuse私はあなたの答えにコメントとしてこれを追加したいと思いましたがコメントに改行を追加するために複数の失敗した試みをした後あきらめました。

そうは言っても、t1IDはtable_1で一意ですが、INFOテーブルでも一意ではありません。

例えば:

Table_1は:
Idフィールド
1 A
2 B

Table_2は:
Idフィールド
1 X
2 Y

INFOそうすると次のようになります。
t1ID t2IDフィールド
1 1いくつか
1 2データ
それぞれ2 1
2 2行

したがって、INFOテーブルで行を一意に識別するためには、t1IDとt2IDの両方が必要です。

1
sactiw