ALTER TABLE для добавления составного первичного ключа - PullRequest
180 голосов
/ 14 января 2012

У меня есть таблица с именем provider. У меня есть три столбца с именами person, place, thing. Могут быть дубликаты людей, дубликаты мест и дубликаты, но никогда не может быть дублирующейся комбинации человек-место-вещь.

Как мне ALTER TABLE добавить составной первичный ключ для этой таблицы в MySQL с этими тремя столбцами?

Ответы [ 6 ]

394 голосов
/ 14 января 2012
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);

Если первичный ключ уже существует, вы хотите сделать это

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);
19 голосов
/ 08 октября 2013

@ Адриан Корниш ответ правильный.Тем не менее, есть еще одна оговорка для удаления существующего первичного ключа.Если этот первичный ключ используется в качестве внешнего ключа другой таблицей, вы получите ошибку при попытке его отбросить.В некоторых версиях 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);

- это не одно и то же. Они оба обеспечивают уникальность этого набора из трех полей, однако с точки зрения индексации есть разница. Поля индексируются слева направо. Например, рассмотрим следующие запросы:

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 в качестве частичного индекса. A не может использовать индекс 1, потому что он не знаетДать место часть индекса.Тем не менее, он все еще может использовать частичный индекс только для одного человека.

D не может использовать любой индекс, потому что он не знает человека.

См. Документацию mysql здесь. для получения дополнительной информации.

15 голосов
/ 16 апреля 2013

Вы можете просто захотеть УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ.Особенно, если у вас уже есть суррогатный ключ.(примером уже существующего суррогатного ключа может быть один столбец, который является AUTO_INCREMENT)

Ниже приведен код sql для уникального ограничения

ALTER TABLE `MyDatabase`.`Provider`
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;
3 голосов
/ 16 мая 2013
alter table table_name add primary key (col_name1, col_name2);
1 голос
/ 24 января 2014

Определенно лучше использовать COMPOSITE UNIQUE KEY, как предложил @GranadaCoder, хотя и немного хитрый пример:

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

0 голосов
/ 08 октября 2013

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

...