ALTER TABLE, um einen zusammengesetzten Primärschlüssel hinzuzufügen

195

Ich habe einen Tisch namens provider. Ich habe drei Säulen genannt person, place, thing. Es kann doppelte Personen, doppelte Orte und doppelte Dinge geben, aber es kann niemals eine doppelte Kombination aus Person, Ort und Ding geben.

Wie würde ich ALTER TABLE ändern, um einen zusammengesetzten Primärschlüssel für diese Tabelle in MySQL mit diesen drei Spalten hinzuzufügen?

David542
quelle

Antworten:

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

Wenn bereits ein Primärschlüssel vorhanden ist, möchten Sie dies tun

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);
Adrian Cornish
quelle
17
@ David542 Nein, tut es nicht - Sie können nur 1 Primärschlüssel haben.
Adrian Cornish
35
@ David: Es ist ein einzelner Primärschlüssel, der aus mehreren Feldern besteht, auch bekannt als zusammengesetzter Schlüssel.
Marc B
3
@ David542 Natürlich können Sie - dies ist ein zusammengesetzter Primärschlüssel, der aus 3 Feldern besteht. Die Kombination der 3 Felder muss eindeutig sein.
Adrian Cornish
2
danke fürs posten - hat mich wirklich aus dem
kampf
1
eine der wertvollsten Antworten in SO :)
alwbtc
21

@Adrian Cornishs Antwort ist richtig. Das Löschen eines vorhandenen Primärschlüssels hat jedoch noch eine weitere Einschränkung. Wenn dieser Primärschlüssel von einer anderen Tabelle als Fremdschlüssel verwendet wird, wird beim Löschen eine Fehlermeldung angezeigt. In einigen Versionen von MySQL war die dortige Fehlermeldung fehlerhaft (ab 5.5.17 ist diese Fehlermeldung immer noch vorhanden

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

Wenn Sie einen Primärschlüssel löschen möchten, auf den von einer anderen Tabelle verwiesen wird, müssen Sie zuerst den Fremdschlüssel in dieser anderen Tabelle löschen. Sie können diesen Fremdschlüssel neu erstellen, wenn Sie ihn nach dem erneuten Erstellen des Primärschlüssels noch möchten.

Bei der Verwendung von zusammengesetzten Schlüsseln ist auch die Reihenfolge wichtig. Diese

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

sind nicht dasselbe. Beide erzwingen die Eindeutigkeit dieser Gruppe von drei Feldern, jedoch gibt es vom Standpunkt der Indizierung einen Unterschied. Die Felder werden von links nach rechts indiziert. Betrachten Sie beispielsweise die folgenden Abfragen:

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 kann den Primärschlüsselindex in der ALTER-Anweisung 1 verwenden.
A kann den Primärschlüsselindex in der ALTER-Anweisung 2 verwenden.
C kann einen der beiden Indizes verwenden.
D kann keinen der beiden Indizes verwenden

A verwendet die ersten beiden Felder in Index 2 als Teilindex. A kann Index 1 nicht verwenden, da es den Zwischenplatzteil des Index nicht kennt. Es kann jedoch immer noch möglich sein, einen Teilindex nur für eine Person zu verwenden.

D kann keinen der beiden Indizes verwenden, da er keine Person kennt.

Weitere Informationen finden Sie in den MySQL-Dokumenten hier .

cs_alumnus
quelle
@All - Könnten Sie bitte das JPA-Äquivalent für dasselbe teilen?
Pra_A
17

Vielleicht möchten Sie einfach eine EINZIGARTIGE EINSCHRÄNKUNG. Vor allem, wenn Sie bereits einen Ersatzschlüssel haben. (Beispiel für einen bereits vorhandenen Ersatzschlüssel wäre eine einzelne Spalte, die AUTO_INCREMENT ist.)

Unten finden Sie den SQL-Code für eine eindeutige Einschränkung

ALTER TABLE `MyDatabase`.`Provider`
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;
granadaCoder
quelle
Vielen Dank, eine Einschränkung ist das, was ich wollte. Ich wusste nicht, wonach ich in diesem ersten Beitrag fragen sollte. Vielen Dank, dass Sie dies dem Thread hinzugefügt haben.
ZaneDarken
Normalerweise verwende ich einen Ersatzschlüssel ...... und füge dann eine eindeutige Einschränkung hinzu. Auf diese Weise ... wenn sich die "Einzigartigkeit" später ändert, ist es nicht sehr dramatisch, die Einschränkung zu optimieren, anstatt mit dem Primärschlüssel herumzuspielen. Und wenn Sie untergeordnete Tabellen haben, deren Fremdschlüssel auf diese Tabelle verweist, müssen Sie nur den Ersatzschlüssel FK, nicht alle 3 Spalten. -
GranadaCoder
3
alter table table_name add primary key (col_name1, col_name2);
Naveen Kumar Alonekar
quelle
1

Es ist definitiv besser, COMPOSITE UNIQUE KEY zu verwenden, wie @GranadaCoder angeboten hat, ein etwas kniffliges Beispiel:

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

Arthur Kushman
quelle
0

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

Glücklich
quelle