Подтвердить что ты не робот

Два столбца в качестве первичных ключей в 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'
4b9b3361

Ответ 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.