ALTER TABLE для добавления составного первичного ключа

160

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

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

Теги:
primary-key
alter-table
composite-primary-key

6 ответов

360
Лучший ответ
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);

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

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);
  • 2
    Это добавляет три уникальных ПК, а не один композитный ПК.
  • 16
    @ David542 Нет, это не так - вы можете иметь только 1 первичный ключ.
Показать ещё 8 комментариев
19

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

15

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

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

ALTER TABLE 'MyDatabase'.'Provider'
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;
  • 0
    Спасибо, ограничение - это то, что я хотел, я не знал, о чем просить в этом первоначальном посте. Спасибо за добавление этого в поток.
  • 0
    Я обычно использую суррогатный ключ ...... затем добавляю уникальное ограничение. Таким образом… если «уникальность» изменится в будущем, отрегулировать ограничение не составит большого труда, чем возиться с первичным ключом. И если у вас есть дочерние таблицы, которые ссылаются на внешний ключ этой таблицы, вам нужно только суррогатный ключ FK, а не все 3 столбца. -
3
alter table table_name add primary key (col_name1, col_name2);
1

Конечно, лучше использовать КОМПОЗИЦИОННЫЙ УНИКАЛЬНЫЙ КЛЮЧ, как, например, @GranadaCoder, немного сложный пример:

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);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню