Навіщо використовувати кілька стовпців в якості первинних ключів (складений первинний ключ)


109

Цей приклад взятий з w3schools .

CREATE TABLE Persons
(
    P_Id int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255),
    CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)

Я розумію, що обидва стовпці разом ( P_Idі LastName) представляють основний ключ для таблиці Persons. Це правильно?

  • Чому хтось хоче використовувати кілька стовпців як основний ключ замість одного стовпчика?
  • Скільки стовпців можна використовувати разом як основний ключ у даній таблиці?


1
@Martijn Peters. Чому відповідь видалено?
PerformanceDBA

Відповіді:


119

Ваше розуміння правильне.

Ви б робили це в багатьох випадках. Одним із прикладів є такі відносини, як OrderHeaderі OrderDetail. ПК OrderHeaderможе бути OrderNumber. PK в OrderDetailможе бути OrderNumberAND LineNumber. Якби це було з цих двох, воно не було б унікальним, але їх поєднання гарантується унікальним.

Альтернативою є використання згенерованого (неінтелектуального) первинного ключа, наприклад, у цьому випадку OrderDetailId. Але тоді ви б не завжди бачили відносини так легко. Деякі люди віддають перевагу одному способу; деякі віддають перевагу іншому.


2
Це корисно, якщо я використовую bran_id та використовую реплікацію між двома базами даних, вирішуватимуть дублікат ідентифікаторів? !!
Mhmd

11
Зауважте, що у багатьох випадках використання згенерованого первинного ключа, ви все ще бажаєте унікального ключа на складених значеннях.
Шматочки бекону

Будь ласка, докладно поясніть "Деякі люди віддають перевагу одному способу, інші віддають перевагу іншому".
Ім'я користувача

1
Заклики детальні? Не впевнений, що сказати. Я знав людей, які вважають за краще мати кілька об'єднаних полів як ключових, тому що простіше зрозуміти, на що вони дивляться, легше інтуїтивно зрозуміти. Я знав інших, які вважають за краще просто присвоїти унікальний ключ кожному рядку, тому що це легше та швидше вводити текст. Це ви просите?
MJB

Це повідомлення призначене для @Username. Я забув його направити.
MJB

26

Іншим прикладом складних первинних ключів є використання таблиць Association. Припустимо, у вас є таблиця людей, яка містить набір людей та групову таблицю, що містить набір груп. Тепер ви хочете створити багато-багато стосунків між людиною та групою. Це означає, що кожна людина може належати до багатьох груп. Ось як виглядатиме структура таблиці за допомогою складного первинного ключа.

Create Table Person(
PersonID int Not Null,
FirstName varchar(50),
LastName varchar(50),
Constraint PK_Person PRIMARY KEY (PersonID))

Create Table Group (
GroupId int Not Null,
GroupName varchar(50),
Constraint PK_Group PRIMARY KEY (GroupId))

Create Table GroupMember (
GroupId int Not Null,
PersonId int Not Null,
CONSTRAINT FK_GroupMember_Group FOREIGN KEY (GroupId) References Group(GroupId),
CONSTRAINT FK_GroupMember_Person FOREIGN KEY (PersonId) References Person(PersonId),
CONSTRAINT PK_GroupMember PRIMARY KEY (GroupId, PersonID))

чудове пояснення: я думаю, що необхідність атрибутів для m-n-відносин (у нормалізованому фасі) є ключовою.
Вовк

можливо, додати трохи
корисного

10

Приклад W3Schools не говорить про те, коли слід використовувати складні первинні ключі, а лише надає приклад синтаксису, використовуючи ту саму прикладну таблицю, що і для інших ключів.

Їх вибір прикладу, можливо, вводить вас в оману, поєднуючи безглуздий ключ (P_Id) та природний ключ (LastName). Цей непарний вибір первинного ключа говорить про те, що наступні рядки є дійсними згідно схеми і необхідні для однозначної ідентифікації учня. Інтуїтивно це не має сенсу.

1234     Jobs
1234     Gates

Подальше читання: велика дискусія на первинному ключі або просто Google meaningless primary keysабо навіть уважно вивчайте це питання

FWIW - Мої 2 центи - уникати первинних ключів з багато стовпцями та використовувати єдине згенероване поле ідентифікатора (сурогатний ключ) як основний ключ та додавати додаткові (унікальні) обмеження, де це необхідно.


1
1) посилання на "велику дискусію на первинному ключі" є особливо дурною, інформація є корисною та хибною. 2) Індексу стовпців, які роблять рядок унікальним, не уникнути. "Сурогатний" ідентифікатор з індексом завжди є додатковим стовпцем та додатковим індексом. Швидше дурне, бо воно зайве. І повільніше.
PerformanceDBA

2
«Велика суперечка первинного ключа» не дурна. Це дуже вагома проблема від розробників, які не є sql розробниками або sql DBA і не проводять весь свій час у sql. Навіть у чистому sql я вважаю за краще мати безглуздий автоматично створений ключ в якості основного ключа під час приєднання, ніж повинен пам'ятати, щоб передавати n біт даних навколо того, щоб бути природним ключем. Запрошуємо до своєї точки зору, але ми будемо раді, що ми не будемо настільки зневажливими.
Роберт Полсон,

4

Ви використовуєте складний ключ (ключ із декількома атрибутами), коли хочете забезпечити унікальність комбінації декількох атрибутів. Один ключ атрибута не досягав би одного і того ж.


1
Що стосується забезпечення унікального ключа, ви можете покластися на комбінацію двох атрибутів, щоб утворити ключ, який логічно неможливо дублювати, приклад особи та дата закінчення з більшого набору даних може бути прикладом.
Джон Марк

3

Так, вони обидва утворюють первинний ключ. Особливо в таблицях, де у вас немає сурогатного ключа , може знадобитися вказати кілька атрибутів як унікальний ідентифікатор для кожного запису (поганий приклад: таблиця з іменем та прізвищем може вимагати, щоб їх поєднання було унікальний).


3

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


1
1) Продуктивність. Не на платформі SQL (можливо, в вигляд "sql" і безкоштовно). 2) Перевага не має значення. Те, що потрібно для цілісності таблиць, є актуальним. 3) "Сурогатний" ідентифікатор з індексом - це завжди додаткова колонка та додатковий індекс. Так що це буде повільніше, на будь-якій платформі. Повторне виконання, ви суперечите собі. 4) Якщо ви не знаєте , як оновити міфічні «мільйон дітей записів в 215 дочірніх таблицях» правильно поставити запитання.
PerformanceDBA

2
Я не погоджуюся з твердженням, що "декілька стовпців у ключі збираються, як правило, більш поганими, ніж сурогатний ключ". Часто потрібен додатковий запит, щоб отримати сурогатний ключ відносин, коли ви його розглядаєте. В цей момент це повна додаткова поїздка у повільніший спосіб.
ttugates

3

Ваше друге запитання

Скільки стовпців можна використовувати разом як основний ключ у даній таблиці?

є специфічною для реалізації: вона визначається у фактичній СУБД, яка використовується. [1], [2], [3] Ви повинні ознайомитись із технічними характеристиками використовуваної системи баз даних. Деякі дуже деталізовані, деякі - ні. Пошук в Інтернеті щодо таких обмежень може бути важким, оскільки термінологія різна. Термін складений первинний ключ повинен бути обов'язковим;)

Якщо ви не можете знайти чіткої інформації, спробуйте створити тестову базу даних, щоб переконатися, що ви можете очікувати стабільного (та конкретного) поводження з порушеннями меж (яких слід очікувати). Будьте обережні, щоб отримати правильну інформацію про це: іноді ліміти накопичуються, і ви бачите різні результати з різними макетами баз даних.



2

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

Я буду використовувати базу даних, яку я колись робив для прикладу, а саме три таблиці в цій таблиці. Я створив базу даних для веб-коміксів кілька років тому. Одна таблиця називалася "комікси" - перелік усіх коміксів, їх назв, назви файлів зображень тощо. Первинним ключем було "comicnum".

У другій таблиці були "символи" - їхні імена та короткий опис. Первинний ключ був на "charname".

Оскільки кожен комікс - за деякими винятками - мав декілька символів, і кожен персонаж з'являвся у кількох коміксах, було недоцільно ставити стовпчик або в «символи», або в «комікси», щоб це відобразити. Натомість я створив третю таблицю під назвою "коміксари", і це був перелік яких персонажів, в яких коміксах. Оскільки ця таблиця по суті приєдналася до двох таблиць, їй потрібні були лише два стовпці: charname та comicnum, а основний ключ був на обох.


1

Ми створюємо складені первинні ключі, щоб гарантувати унікальність значень стовпців, які складають один запис. Це обмеження, яке допомагає запобігти вставленню даних, які не слід дублювати.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.