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

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

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

6 ответов


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

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

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

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


вам может просто понадобиться уникальное ограничение. Особенно если у вас уже есть суррогатный ключ. (пример: AUTO_INCREMENT)

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

alter table table_name add primary key (col_name1, col_name2);

определенно лучше использовать составной уникальный ключ, как предложил @GranadaCoder, немного сложный пример:

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


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