2010-04-15 5 views
18

Я пытаюсь научиться использовать ключи и нарушать привычку обязательно иметь идентификаторы типов SERIAL для всех строк во всех моих таблицах. В то же время я также выполняю отношения «многие-ко-многим», поэтому требуя уникальных значений в любом столбце таблиц, которые координируют отношения, будет мешать этому.Первичный ключ для нескольких столбцов в MySQL 5

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

+0

Возможный дубликат [Как правильно создавать составные первичные ключи - MYSQL] (http://stackoverflow.com/questions/5835978/how-to-properly-create-composite-primary-keys-mysql) –

+0

Не удается быть дубликатом чего-то, опубликованного 3 года спустя. – Kaji

+0

http://meta.stackexchange.com/questions/147643/should-i-vote-to-close-a-duplicate-question-even-though-its-much-newer-and-ha ;-) –

ответ

39

Цитируется по CREATE TABLE Syntax странице:

первичный ключ может быть несколько столбцов индекс. Однако вы не можете создать индекс с несколькими столбцами , используя атрибут ключевого ключа PRIMARY KEY в столбце . Выполнение этого только отмечает , что один столбец как первичный. Вы, , должны использовать отдельный PRIMARY KEY (index_col_name, ...).

Нечто подобное можно использовать для нескольких столбцов первичных ключей:

CREATE TABLE 
    product (
     category INT NOT NULL, 
     id INT NOT NULL, 
     price DECIMAL, 
     PRIMARY KEY(category, id) 
    ); 

От 13.6.4.4. FOREIGN KEY Constraints

+0

Shouldn ' t вы включаете цену в PK (категория, идентификатор, цена) вашего примера? Он просит «любую колонку» и «по всем колонкам»? ... и затем добавить суровый комментарий об этом субоптимальном, медленном и никогда не нуждающемся в реальной жизни? (ДА! Я вот-вот нахожусь здесь :-) – lexu

+0

Согласен. Все столбцы должны быть там – fiacobelli

+0

Не работает вообще в моем случае. Например, если я использую другую категорию, но тот же идентификатор, покажите мне дублированный ключ. –

17

Первичный ключ является понятие домена, которое однозначно (обязательно и достаточно) идентифицирует объект среди аналогичных субъектов. Сводный (многоколоночный) первичный ключ имеет смысл только тогда, когда часть ключа относится к конкретному экземпляру другого объекта домена.

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

Теперь вы хотите объединить свою библиотеку с библиотекой своего соседа, но все же сможете отличить, к кому принадлежит книга. Домен теперь шире и первичный ключ теперь (владелец, book_id).

Таким образом, создание каждого первичного ключевого композита не должно быть вашей стратегией, но вы должны использовать его, когда это необходимо.

Теперь некоторые факты о MySQL. Если вы определяете составной первичный ключ и хотите, чтобы RDBSM автоматически определял идентификаторы для вас, вы должны знать о различии между поведением MyISAM и InnoDB.

Предположим, нам нужна таблица с двумя полями: parent_id, child_id. И мы хотим, чтобы child_id был автоинкрементным.

MyISAM будет автоматически автоинкрементно в пределах записей с одним и тем же parent_id, и InnoDB будет автоинкремент уникально в пределах всей таблицы.

В MyISAM вы должны определить первичный ключ как (parent_id, child_id) и в InnoDB as (child_id, parent_id), поскольку поле с автоинкрементами должно быть самым левым компонентом в первичном ключе в InnoDB.

+1

Это выдающийся ответ. – Dakatine

1

Первичный ключ является уникальным значением для строки. Нет смысла включать цену, стоимость которой может измениться. Представьте себе, если бы вам пришлось менять большой диапазон цен, тогда все эти значения первичного ключа изменились бы. Какой беспорядок будет!