Как правильно создавать составные первичные ключи - MYSQL - PullRequest
160 голосов
/ 29 апреля 2011

Вот грубое упрощение интенсивной установки, с которой я работаю.table_1 и table_2 оба имеют суррогатные первичные ключи с автоинкрементом в качестве идентификатора.info - это таблица, которая содержит информацию о table_1 и table_2.

table_1 (id, field)  
table_2 (id, field, field)
info ( ???, field)

Я пытаюсь решить, должен ли я сделать первичный ключ info составным из идентификаторов изtable_1 и table_2.Если бы я это сделал, что из этого имеет больше смысла?
(в этом примере я объединяю ID 11209 с ID 437)

INT(9) 11209437 (я могу себе представить, почему это плохо)
VARCHAR (10) 11209-437
DECIMAL (10,4) 11209.437

Или что-то еще?

Можно ли использовать это как первичный ключ в базе данных MYSQL MYISAM?

Ответы [ 8 ]

301 голосов
/ 29 апреля 2011

Я бы использовал составной (многостолбцовый) ключ.

CREATE TABLE INFO (
    t1ID INT,
    t2ID INT,
    PRIMARY KEY (t1ID, t2ID)
) 

Таким образом, вы можете использовать t1ID и t2ID в качестве внешних ключей, указывающих на их соответствующие таблицы.

20 голосов
/ 29 апреля 2011

Я бы не стал делать первичный ключ таблицы «info» составным из двух значений из других таблиц.

Другие могут лучше сформулировать причины, но неправильно иметь столбец, который на самом деле состоит из двух частей информации.Что делать, если вы хотите по какой-то причине отсортировать по идентификатору из второй таблицы?Что если вы хотите посчитать, сколько раз значение из любой таблицы присутствует?

Я бы всегда оставлял их как два отдельных столбца.Вы можете использовать первичный ключ с двумя столбцами в mysql ... PRIMARY KEY (id_a, id_b) ... но я предпочитаю использовать уникальный индекс из двух столбцов и иметь поле первичного ключа с автоматическим приращением.

14 голосов
/ 26 марта 2013

синтаксис: CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3), например ::

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

приведенный выше пример будет работать, если вы пишете его во время создания таблицынапример ::

CREATE TABLE person (
   P_Id int ,
   ............,
   ............,
   CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);

, чтобы добавить это ограничение к существующей таблице, вам необходимо следовать следующему синтаксису

ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)
5 голосов
/ 23 августа 2017

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

alter table employee add primary key(emp_id,emp_name);
4 голосов
/ 12 марта 2013

Составные первичные ключи - это то, что вы хотите, где вы хотите создать связь «многие ко многим» с таблицей фактов. Например, у вас может быть пакет аренды на время отпуска, который включает в себя ряд свойств. С другой стороны, собственность может также быть доступна как часть ряда пакетов аренды, либо самостоятельно, либо вместе с другими объектами. В этом сценарии вы устанавливаете связь между свойством и пакетом аренды с помощью таблицы фактов свойства / пакета. Связь между свойством и пакетом будет уникальной, вы можете присоединиться только с помощью property_id с таблицей свойств и / или package_id с таблицей пакетов. Каждое отношение уникально, и ключ auto_increment является избыточным, поскольку он не будет отображаться ни в одной другой таблице. Следовательно, определение составного ключа является ответом.

3 голосов
/ 17 октября 2013

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

Например, в каждом штате США есть набор уникальных округов Конгресса. Хотя во многих штатах CD-5 может быть отдельно, в любом из 50 штатов никогда не будет более одного CD-5, и наоборот. Поэтому создание поля автонумерации для Массачусетского CD-5 было бы излишним.

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

Так что, хотя я не отвечаю на первоначальный вопрос, я, безусловно, ценю прямой ответ Адама.

1 голос
/ 05 июня 2014

@ AlexCuse Я хотел добавить это как комментарий к вашему ответу, но сдался после неоднократной неудачной попытки добавить новые строки в комментариях.

При этом t1ID уникален в таблице_1, но это не делает еготакже уникален в таблице INFO.

Например:

Table_1 имеет:
Поле идентификатора
1 A
2 B

Таблица_2 имеет:
Поле идентификатора
1 X
2 Y

INFO , тогда может иметь:
поле t1ID t2ID
1 1 немного
1 2 данных
2 1 в каждом
2 2 строки

Таким образом, в таблице INFO для уникальной идентификации строки вам необходимы и t1ID, и t2ID

1 голос
/ 07 февраля 2012
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);
...