Как правильно создать составные первичные ключи-MYSQL

вот грубое упрощение интенсивной установки, с которой я работаю. 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 DB?

8 ответов


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

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

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


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

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

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


синтаксис 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)

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


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

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

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

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


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

alter table employee add primary key(emp_id,emp_name);

CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);

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

тем не менее, t1ID уникален в table_1, но это не делает его уникальным и в таблице INFO.

например:

таблице table_1 есть:
Поле Id
1 A
2 B

Table_2 есть:
Поле Id
1 X
2 Y

INFO то есть:
t1ID t2ID поле
1 1 часть
1 2 Сведения
2 1 в каждой
2 2 строки

поэтому в таблице INFO для уникальной идентификации строки вам нужны как t1ID, так и t2id