複合主キーを追加するためのALTER TABLE


195

というテーブルがありますprovider。私はと呼ばれる3つの列を持っていますpersonplacething。重複する人物、重複する場所、および重複するものが存在する可能性がありますが、重複した人物と場所とモノの組み合わせが存在することはありません。

これらの3つの列を持つMySQLでこのテーブルの複合主キーを追加するには、どのようにALTER TABLEを実行しますか?

回答:


424
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);

主キーがすでに存在する場合は、これを行います

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);

17
@ David542いいえ、ありません-主キーは1つしか持てません。
エイドリアンコーニッシュ、

35
@David:複数のフィールドで構成される単一の主キー、つまり複合キーです。
マルクB

3
@ David542もちろん可能です-これは、3つのフィールドで構成される複合主キーです。3つのフィールドの組み合わせは一意である必要があります。
エイドリアン・コーニッシュ

2
投稿してくれてありがとう-本当にuiとの戦いから抜け出した
plditallo 2013

1
SOで最も貴重な答えの1つ:)
alwbtc

21

@エイドリアンコーニッシュの答えは正しいです。ただし、既存の主キーを削除することには、別の注意事項があります。その主キーが別のテーブルによって外部キーとして使用されている場合、それを削除しようとするとエラーが発生します。mysqlの一部のバージョンでは、そこにエラーメッセージがありました(5.5.17以降、このエラーメッセージはまだ

alter table parent  drop column id;
ERROR 1025 (HY000): Error on rename of
'./test/#sql-a04_b' to './test/parent' (errno: 150).

別のテーブルによって参照されている主キーを削除する場合は、最初にその別のテーブルの外部キーを削除する必要があります。主キーを再作成した後も必要な場合は、その外部キーを再作成できます。

また、複合キーを使用する場合は、順序が重要です。これら

1) ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
and
2) ALTER TABLE provider ADD PRIMARY KEY(person,thing,place);

同じではありません。どちらも3つのフィールドのセットに一意性を適用しますが、インデックスの観点からは違いがあります。フィールドには、左から右にインデックスが付けられています。たとえば、次のクエリについて考えます。

A) SELECT person, place, thing FROM provider WHERE person = 'foo' AND thing = 'bar';
B) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz';
C) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz' AND thing = 'bar';
D) SELECT person, place, thing FROM provider WHERE place = 'baz' AND thing = 'bar';

BはALTERステートメント1で
主キーインデックスを使用できますAはALTERステートメント2で主キーインデックスを
使用できますCはいずれかのインデックスを使用できます
Dはどちらのインデックスも使用できません

Aは、インデックス2の最初の2つのフィールドを部分インデックスとして使用します。は、インデックスの中間の場所の部分を認識していないため、インデックス1を使用できません。それでも、人だけで部分インデックスを使用できる場合があります。

Dは人を知らないため、どちらのインデックスも使用できません。

詳細については、mysqlのドキュメントを参照してください。


@All-JPAと同等のものを共有していただけませんか?
Pra_A

17

あなたは単にユニークな制約が欲しいかもしれません。特に、すでに代理キーがある場合。(既存の代理キーの例は、AUTO_INCREMENTである単一の列です)

以下は、一意の制約のSQLコードです

ALTER TABLE `MyDatabase`.`Provider`
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;

ありがとう、制約は私が欲しかったものです、私はこの最初の投稿で何を求めるべきか分かりませんでした。これをスレッドに追加していただきありがとうございます。
ZaneDarken 14

私は通常、代理キーを使用します。次に、一意の制約を追加します。このように...「一意性」が将来変化する場合、主キーをいじるのではなく、制約を微調整することはそれほどドラマではありません。また、外部キーがこのテーブルを参照する子テーブルがある場合は、3つの列すべてではなく、代理キーのみをFKする必要があります。–
granadaCoder 2014


1

@GranadaCoderが提供するように、少し複雑な例ですが、COMPOSITE UNIQUE KEYを使用する方が間違いなく優れています。

ALTER IGNORE TABLE table_name ADD UNIQUES INDEX idx_name(some_id, another_id, one_more_id);


0

ALTER TABLE table_name DROP PRIMARY KEY,ADD PRIMARY KEY (col_name1, col_name2);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.