Два столбца в качестве первичных ключей в mysql?
Сегодня я узнал, что вы можете иметь первичный ключ, используя два столбца (tsql). PK должен быть уникальным, но оба столбца не являются (комбо должно быть уникальным).
Я думал, что это очень круто. Было, по крайней мере, два вопроса SO, на которых я спросил, где люди кричали на меня, что я делаю свои (mysql) базы данных не так, как только один человек говорит, что я сделал это хорошо. Итак... это оставляет мне какое-то сомнение.
Делает ли это то, что я думаю, что он делает?
create table User(
id INT primary key AUTO_INCREMENT ,
ipaddr TEXT NOT NULL ,
email TEXT NOT NULL
);
create table test(
a INT NOT NULL ,
b INT NOT NULL ,
dummy INT NOT NULL ,
FOREIGN KEY (a) REFERENCES User(id),
FOREIGN KEY (b) REFERENCES User(id),
PRIMARY KEY(a,b)
);
Я побежал ниже, так что кажется, что я делаю то, что думаю (комбо должно быть уникальным. Но одно и то же значение в столбце не обязательно должно быть уникальным). Должен ли я знать что-то? Должна быть причина, о которой никто не упоминал мне в отношении mysql?
mysql> insert into test(a,b,dummy) select 1,1,1;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into test(a,b,dummy) select 1,2,2;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into test(a,b,dummy) select 2,1,3;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into test(a,b,dummy) select 2,2,4;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into test(a,b,dummy) select 1,2,5;
ERROR 1062 (23000): Duplicate entry '1-2' for key 'PRIMARY'
Ответы
Ответ 1
Вы уже думали об этом:
- первичные ключи (независимо от того, сколько столбцов задействовано) должны быть уникальными
- ваш первичный ключ - это два столбца a, b
Поэтому a и b вместе должны быть уникальными.
Индивидуальное значение a и b не имеет значения.
Ответ 2
Да, это нормально делать в SQL, и он работает (имея составной первичный ключ, в котором несколько полей вместе составляют уникальное значение).
Две заметки:
-
Убедитесь, что это необходимо. Это часто, и тогда это хорошо. Но иногда это признак того, что вам необходимо нормализовать вашу модель данных.
-
Я думаю, что вы не хотите делать, а b - это внешние ключи из другой таблицы, а затем сделать их составным первичным ключом вашей таблицы. Что произойдет, если вы настроите каскадное удаление, в котором один идентификатор пользователя, а не другой удаляется? Таким образом, составной первичный ключ прекрасен, но тогда вы не хотите получать "несвязанные" внешние ключи.
Ответ 3
Ваше мышление хорошее. Я часто использую многоадресные первичные ключи, просто потому, что делает мою структуру базы данных более логичной, управляемой и читаемой. Вы можете думать о многопольных первичных ключах, таких как уникальное имя. Например:
Первичные ключи с несколькими полями:
(First ,Middle, Last)
Пример значений:
('Michael', 'A.', 'Kline')
Может быть много людей с "Первым" именем "Майкл" и/или "Среднее" имя "А." и/или "Наилучшее" имя "Kline", но, что касается вашей базы данных, может быть только один "Майкл А. Клайн".
Обычно первичный ключ с несколькими полями представляет собой комбинацию других первичных ключей из других таблиц, а содержимое записи описывает контент, зависящий от конкретных значений ключа. Например:
Table #1: Student Records (KEY: student_id)
Table #2: Course Records (KEY: course_id)
Table #3: Student Grades (KEY: student_id, course_id)
Надеюсь, что это поможет.
Ответ 4
Да, вы должны знать о дублировании PRIMARY_KEY, который представляет собой комбинированный ключ в вашем случае, чтобы не дублироваться.
В любом случае, когда вы устанавливаете два PK, это означает, что ваша подпись PK1 + PK2, чтобы вы могли дублировать PK1 или PK2, но не оба.
Надеюсь, что я помог
Ответ 5
Также одно замечание:
Первичные ключи автоматически индексируются в MySQL.
И порядок столбцов, упоминаемый в первичном ключе, имеет значение для производительности, как указано здесь
Ответ 6
Я считаю, что происходит, что парные столбцы являются первичными. Например, вы знаете, что не можете иметь повторяющийся первичный столбец Ex: если col "a" является основным, вы не можете иметь две строки, которые имеют одинаковое значение для a.
В этом примере у вас есть два праймера; что означает, что вы можете иметь только одно уникальное значение для каждой пары col.
Например, если col 'a' и 'b' являются первичными, а 'c' не является:
| б | с
1,2,3 работы
1,4,5 работ
а также
5,1,6 работ
9,1,10 работ
но вы не можете:
9,8,10
9,8,6, потому что для этой пары (9,8) вы можете иметь только одно уникальное значение...
Имеет ли это смысл или вы хотите, чтобы я подробно разбирался?
Ответ 7
ALTER TABLE TableName
DROP PRIMARY KEY, ADD PRIMARY KEY (column1
, column2
);
если вы установили первичный ключ ранее, попробуйте это.
Ответ 8
Чтобы было легче объяснить, я буду использовать только одну таблицу. Создайте таблицу с двумя столбцами типа int и PK на них обоих. Как и в вопросе.
create table test(
a INT NOT NULL ,
b INT NOT NULL ,
PRIMARY KEY(a,b));
Теперь мы можем добавлять строки, пока не получим ошибку
insert into test values(1,1);
Query OK, 1 row affected (0,00 sec)
insert into test values(1,2);
Query OK, 1 row affected (0,00 sec)
insert into test values(1,1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
Это логично, поскольку объединенные значения двух столбцов, составляющих PK, больше не являются уникальными, когда будет выполняться этот последний оператор.
Разрешено хранить 2x значение 1 в a, потому что это не PK. PK - это объединенное значение столбцов a и b.