Яка найкраща практика для первинних ключів у таблицях?


256

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

  1. Ідентифікаційний цілий стовпець, який автоматично збільшується.
  2. Унікальний ідентифікатор (GUID)
  3. Колонка з коротким символом (x) або цілим числом (або іншим відносно невеликим числовим типом), що може слугувати стовпцем ідентифікатора рядків

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

Здебільшого всі інші таблиці матимуть ціле ціле автоматичне збільшення або первинний ключ унікального ідентифікатора.

Питання :-)

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

  • дата / характер
  • дата / ціле число
  • дата / варчар
  • char / nvarchar / nvarchar

Чи є справжня справа для цього? Я б завжди визначав ідентифікаційний або унікальний стовпчик ідентифікатора для цих випадків.

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

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

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


Я знайшов вміння бази даних: Здоровий підхід до вибору первинних ключів добре прочитаний, і я дотримуюся більшості викладених пунктів.
user2864740

Відповіді:


254

Я дотримуюся кількох правил:

  1. Первинні ключі повинні бути настільки ж маленькими, наскільки це необхідно. Віддайте перевагу числовому типу, оскільки числові типи зберігаються у набагато більш компактному форматі, ніж формати символів. Це тому, що більшість первинних ключів будуть сторонніми ключами в іншій таблиці, а також використовуються в декількох індексах. Чим менший ваш ключ, тим менший індекс, тим менше сторінок у кеші ви будете використовувати.
  2. Первинні ключі ніколи не повинні змінюватися. Оновлення первинного ключа завжди не повинно виникати. Це тому, що він, швидше за все, використовується в декількох індексах і використовується як зовнішній ключ. Оновлення єдиного первинного ключа може викликати пульсаційний ефект змін.
  3. НЕ використовуйте "первинний ключ вашого проблеми" як первинний ключ вашої логічної моделі. Наприклад, номер паспорта, номер соціального страхування або номер договору працівника, оскільки ці "первинний ключ" можуть змінюватися для реальних ситуацій.

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


3
Мені це подобається! Чи є у вас будь-яка документація на основі ваших "правил"? Дякую!
Ллойд Коттен

4
Ні, просто досвід. У роботі з "малими" базами даних цей матеріал не має великого значення. Але коли ви маєте справу з великим db, усі дрібниці мають значення. Уявіть собі, якщо у вас є 1 мільярд рядків з int або long pk, порівняно з використанням тексту або guide. Є величезна різниця!
Логічний розум

44
Просто пам’ятайте, щоб поставити цей унікальний індекс на природний ключ (якщо він дійсно існує, що часто не буває), коли ви використовуєте штучний ключ.
HLGEM

3
@Lloyd Cotten: Ось що говорить провайдер великих даних у підтримку правила № 1: skyfoundry.com/forum/topic/24 . Це переконало мене повернутися до Ints
варильні панелі

4
навіть якщо ви "знаєте", що "природний ключ малий і ніколи не зміниться", подумайте двічі. "Ми ніколи не повторно використовуємо ці коди" - це відомі останні слова .... Про єдині речі, які належать до категорій малих, ніколи не змінюються, - це iso та інші стандарти (коди країн, коди аеропортів iata,). Такі речі, як "що є двозначним представленням для цього внутрішнього бренду" ... подумайте двічі, перш ніж припускати, що "воно" ніколи не зміниться, ви за одне фінансове рішення відмовитися від перебудови бази даних.
Ендрю Хілл

90

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

  • Штати Америки: я хотів би вказати state_code ("TX" для Техасу тощо), а не state_id = 1 для Техасу
  • Співробітники: Я б зазвичай створив штучний__співробітник, тому що важко знайти щось інше, що працює. SSN або еквівалент може працювати, але можуть виникнути такі проблеми, як новий столяр, який ще не постачав свій SSN.
  • Історія заробітної плати працівника: (співробітник_id, старт_дачі). Я б не створив штучну_службову_саларію_історію_ід. Якому моменту це послужило б (крім "дурної консистенції" )

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

state_id    state_code   state_name
137         TX           Texas
...         ...          ...
249         TX           Texas

9
У деяких випадках із сервером SQL 2005/2008 природний (текстовий) ключ може бути швидшим, ніж клавіша int. У мене є додаток із зручним кодом 7-8 символів, який ми використовуємо в якості основного ключа, і це було швидше (і часто зручніше), ніж сурогат int. Код нам так чи інакше був потрібний, щоб ми могли читати / запам'ятовувати людину код, який ми могли б безпечно без конфлікту переносити на інший екземпляр програми (декілька сайтів, що об’єднуються у більшу сторінку).
ламбак

1
+1 Хороша відповідь. Однак я би отримав, щоб офіцер з персоналу був довіреним джерелом ідентифікатора працівника, тобто офіцером, відповідальним за перевірку працівників у реальному житті, які, ймовірно, використовують ідентифікатори, такі як SSN, брати довідки тощо. Кадровий відділ повинен довіряти джерело ідентифікаторів співробітників, а не СУБД!
одного дня, коли

@ onedaywhen- Я б не хотів. довіряйте особовому складу. Люди виїжджають, приходять нові і мають різні ідеї. Надайте їм доступ до того ідентифікатора, який вони вважають унікальним / вони хочуть використовувати, але внутрішньо для db, dba повинен приймати своє власне рішення
Dave Pile

1
Зауважте, що SSN не обов’язково унікальний у кожній країні. Принаймні , в Австрії, кілька людей , можливо , одні і ті ж номери
Maja

Також у деяких країнах (я думаю, навіть у США) вони фактично рекомендують не ділитися SSN.
Штійн де Вітт

25

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

Скажімо, у нас є такі таблиці та стовпці:

Company:
  CompanyId   (primary key)

CostCenter:
  CompanyId   (primary key, foreign key to Company)
  CostCentre  (primary key)

CostElement
  CompanyId   (primary key, foreign key to Company)
  CostElement (primary key)

Invoice:
  InvoiceId    (primary key)
  CompanyId    (primary key, in foreign key to CostCentre, in foreign key to CostElement)
  CostCentre   (in foreign key to CostCentre)
  CostElement  (in foreign key to CostElement)

Якщо останній біт не має сенсу, він Invoice.CompanyIdє частиною двох закордонних ключів, одного до таблиці CostCentre і одного до таблиці CostElement . Первинний ключ - ( InvoiceId , CompanyId ).

У цій моделі неможливо відкрутити та посилати CostElement від однієї компанії та CostCentre від іншої компанії. Якби сурогатний ключ був використаний у таблицях CostElement та CostCentre , це було б.

Чим менше шансів викрутити, тим краще.


6
Це недооцінений недолік при використанні сурогатних ключів. Якщо у таблиці є сурогатний ключ, я все одно можу використовувати його для таких видів обмежень. На жаль, хоча обмеження вимагає індексу, і створювати унікальний індекс на (суррогат_колій, інший_колонці) просто дивно, коли (суррогат_колій) унікальний сам по собі. Крім того, (other_column) часто абсолютно зайвий у таблиці карт, оскільки (surrogate_key) унікальний у іноземній. Сурогати дійсно можуть зіпсувати речі.
Самуель Даніельсон

24

Я уникаю використання природних ключів з однієї простої причини - людської помилки. Хоча природні унікальні ідентифікатори часто доступні (SSN, VIN, номер рахунку тощо), люди вимагають, щоб вони ввели їх правильно. Якщо ви використовуєте SSN в якості основного ключа, хтось переносить пару чисел під час введення даних, і помилка виявляється не відразу, то ви зіткнулися зі зміною основного ключа.

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


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

13

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

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

Це стара дискусія. Я віддаю перевагу сурогатним ключам у більшості ситуацій.

Але немає виправдання для відсутності ключа.

RE: EDIT

Так, суперечок щодо цього багато: D

Я не бачу очевидних переваг у натуральних ключах, окрім того, що вони є природним вибором. Ви завжди будете думати в Name, SocialNumber - чи щось подібне - замість idPerson .

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

Коли ви звикаєте до сурогатів, це здається більш чистим і керованим.

Зрештою, ви дізнаєтесь, що це лише питання смаку чи мислення. Люди "думають краще" за допомогою природних ключів, а інші - ні.


13
Люди «думають краще» за допомогою природних ключів. Машини та бази даних, не варто.
FDCastel

11

У таблицях постійно повинен бути первинний ключ. Коли це не так, це повинні були бути поля з автоматичним збільшенням.

Інколи люди опускають первинний ключ, оскільки вони передають багато даних, і це може сповільнити (залежно від бази даних) процес. АЛЕ його слід додавати після нього.

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


Я згоден. А у випадку, коли потрібно вставити багато даних, видаліть обмеження первинного ключа (або використовуйте INSERT IDENTITY ON у TSQL) і поверніть його після цього :)
Andrew Rollings

1
Є винятки: таблиці посилань очевидно
annakata

Інша причина: Якщо немає ПК / унікального ключа, браузери таблиць (я маю на увазі щось на зразок Access / SQL Server Management Studio) відмовляться оновлювати / видаляти один рядок із дублюваним рядком. Для цього вам доведеться написати SQL.
Dennis C

Досить часто пропускати ПК із таблиці фактів сховища даних. В Oracle ви можете посилатися на псевдоколонку ROWID як унікальний ідентифікатор за короткий термін (тобто не зберігати його десь і очікувати, що він не зміниться)
Девід Олдрідж

9

Окрім усіх цих гарних відповідей, я просто хочу поділитися гарною статтею, яку я щойно прочитав, - великою дискусією первинного ключа .

Просто навести кілька пунктів:

При виборі первинного ключа для кожної таблиці розробник повинен застосувати кілька правил:

  • Первинний ключ повинен однозначно ідентифікувати кожен запис.
  • Значення основного ключа запису не може бути нульовим.
  • Первинний ключ-значення повинен існувати під час створення запису.
  • Первинний ключ повинен залишатися стабільним - ви не можете змінювати поля первинного ключа.
  • Первинний ключ повинен бути компактним і містити найменші можливі атрибути.
  • Значення первинного ключа неможливо змінити.

Природні ключі (як правило) порушують правила. Сурогатні ключі відповідають правилам. (Ви краще прочитайте цю статтю, вона вартує вашого часу!)


7

Що особливого у первинному ключі?

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

Таблиці (та зв’язки таблиць) містять факти про інформацію, яку ви хочете записати. Ці факти повинні бути самостійними, осмисленими, легко зрозумітими і не суперечливими. З точки зору проектування, інші таблиці, додані або вилучені із схеми, не повинні впливати на відповідну таблицю. Повинна бути мета зберігання даних, що стосуються лише самої інформації. Розуміння того, що зберігається в таблиці, не повинно вимагати проведення науково-дослідного проекту. Жоден факт, що зберігається з однаковою метою, не повинен зберігатися не один раз. Клавіші - це ціла або частина записуваної інформації, яка є унікальною, а первинний ключ - це спеціально призначений ключ, який повинен бути первинною точкою доступу до таблиці (тобто його слід вибирати для узгодженості та використання даних, а не просто вставляти виконання).

  • ВІДПОВІДЬ: На жаль побічний ефект більшості баз даних, що розробляються та розробляються програмістами прикладних програм (що я іноді), полягає в тому, що те, що найкраще для програми або рамки програми, часто визначає вибір первинного ключа для таблиць. Це призводить до цілочисельних і GUID-ключів (оскільки їх просто використовувати для рамок додатків) та монолітних конструкцій таблиць (оскільки вони зменшують кількість об'єктів рамки програми, необхідних для представлення даних у пам'яті). Ці рішення, засновані на розробці баз даних, призводять до значних проблем узгодженості даних при використанні в масштабі. Створені таким чином рамки застосування, природно, призводять до створення таблиці за часом. "Часткові записи" створюються в таблицях і даних, заповнених з часом. Уникає взаємодії між кількома таблицями або при використанні викликає непослідовні дані, коли програма функціонує неправильно. Ці конструкції призводять до безглуздих (або важких для розуміння) даних, розповсюдження даних по таблицях (ви повинні подивитися на інші таблиці, щоб зрозуміти поточну таблицю) та дублюваних даних.

Говорили, що первинних ключів має бути стільки, скільки потрібно. Я б сказав, що ключі повинні бути лише стільки, скільки потрібно. Слід уникати випадкового додавання безглуздих полів до таблиці. Ще гірше зробити ключ із випадково доданого безглуздого поля, особливо коли він руйнує залежність приєднання з іншої таблиці до первинного ключа. Це розумно лише в тому випадку, якщо в таблиці немає хороших ключів-кандидатів, але це явище, безумовно, є ознакою поганої конструкції схеми, якщо вона використовується для всіх таблиць.

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

Сказавши це, я вдячний за багато погано розроблених баз даних, які існують сьогодні в бізнесі (безглузді-сурогатні-ключі-дані-пошкоджені-1NF-гегемоти), тому що це означає, що для людей, які розуміють правильний дизайн бази даних, існує нескінченна кількість роботи. . Але з сумної сторони, це іноді змушує мене відчувати себе Сизіфом, але я обділяю, що він мав один чорт 401 к (до аварії). Тримайтеся подалі від блогів та веб-сайтів для важливих питань дизайну бази даних. Якщо ви проектуєте бази даних, знайдіть дату CJ. Ви також можете посилатися на Celko на SQL Server, але тільки якщо ви спочатку тримаєте ніс. З боку Oracle, посилання на Тома Кейта.


1
"За цією логікою ви ніколи не повинні видаляти запис із таблиці одним ключем, а потім додавати інший запис другим ключем." - Для цього є випадок, і це фактично те, що буде виконано пунктом "ON DELETE RESTRICT" на зовнішньому ключі. У деяких випадках (скажімо, де потрібен слід аудиту) "видалене" булеве поле було б краще, ніж дозволяти видалити запис.
Ваз

6

Природний ключ, якщо він є, як правило, найкращий. Отже, якщо datetime / char однозначно ідентифікує рядок, і обидві частини мають значення для рядка, це чудово.

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


9
Зазвичай найкраще? У мене немає ніякої наукової бази, але я майже позитивний, більшість людей віддають перевагу сурогатному ключу над природним. У багатьох випадках немає природного ключа.
JC.

3
ЗАВЖДИ повинен бути природний ключ для будь-якого рядка вашої бази даних. Цей "природний" ключ може бути чимось породженим у діловому світі чи вашій технічній системі, але він повинен завжди існувати.
Том H

2
Якщо у вашому світі саме так було визначено єдиний спосіб визначити рядок у таблиці, то так. Звичайно, коли дизайнер вирішує створити GUID для ПК, це зазвичай тому, що вони не виконали роботу, щоб знайти НАДІЙНИЙ природний ключ, тому в такому випадку GUID НЕ є природним ключем.
Том Н

8
2. Якщо ви візьмете свій ключ від світу природи, природний світ зміниться, щоб зламати ваш ключ. Якщо ви використовуєте номер телефону, ви отримаєте двох користувачів з одного домогосподарства. Якщо ви використовуєте прізвище, вони одружуються. Якщо ви використовуєте SSN, закони про конфіденційність зміняться і вимагатимуть їх видалення.
Джеймс Орр

2
@Barry: RE: # 2. якщо природний світ зміниться, і це призведе до зміни вашого природного ключа, це означає, що ви зробили погану роботу, вибравши природний ключ. За визначенням, природний ключ не змінюється з часом.
Том Н

6

Ось моє власне правило великих пальців, на якому я влаштувався після 25+ років досвіду розвитку.

  • Усі таблиці повинні мати основний ключ одного стовпця, який збільшується автоматично.
  • Включіть його в будь-який вигляд, який повинен бути оновлений
  • Первинний ключ не повинен мати жодного значення в контексті вашої програми. Це означає, що це не повинен бути SKU, або номер рахунку, ідентифікатор співробітника чи будь-яка інша інформація, яка має значення для вашої заявки. Це просто унікальний ключ, пов'язаний з сутністю.

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

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

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


5

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

"Кожен клієнт моєї бази даних має і повинен мати SSN." Бам, готово, зробіть це первинним ключем і виконайте з ним. Просто пам’ятайте, коли ваше ділове правило змінюється, коли ви спалюєте

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


8
І я бачив дані, де SSN не є унікальним, хоча і має бути. Будьте дуже обережні до природних ключів, якщо ви імпортуєте свої дані з іншого джерела!
HLGEM

2
Якщо ви піддаєтесь крадіжці особи, ви можете змінити свій номер соціального страхування. Є ще чотири ситуації, коли вони змінять ваш номер, і вони вказані на сайті ssa.gov.
Zvi Twersky

4

Я підозрюю, що розроблена газета терапія Стівена А. Лоу необхідна для дизайнера оригінальної структури даних.

Окрім того, GUID як первинний ключ може бути свиней продуктивності. Я б не рекомендував це.


2
Сказати, що його свиня за продуктивністю - це передчасна оптимізація. Інструкції потрібні в деяких випадках (відключені клієнти, майбутнє злиття таблиці, реплікація)
JC.

2
"Передчасна оптимізація" - це надмірно використана фраза щодо SO (IMHO)! Так, GUID можуть знадобитися в деяких випадках, але Ендрю справедливо вказує, що вони не повинні використовуватися як тип даних за замовчуванням, незалежно від того, потрібен він чи ні.
Тоні Ендрюс

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

Або використовувати обидва. Майте основний ключ int / long для швидкого швидкого вибору та приєднання, а потім мати орієнтир. Принаймні, це я і роблю. Це неправильно? Чи не повинен я цього робити? :)
Ендрю Роллінгз

Я також використовую обидва стовпчики. Але не впевнений, неправильно це чи ні. Ви знайшли це @AndrewRollings?
YÒGÎ

3

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

Це цілком прийнятне рішення, ідіть сюди для отримання додаткової інформації :)


3

Я теж завжди використовую числовий стовпчик ідентифікатора. В оракулі я використовую число (18,0) без будь-якої реальної причини вище числа (12,0) (або все, що є інтом, а не довгим), можливо я просто не хочу ніколи турбуватися про отримання кількох мільярдів рядків db!

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

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


2
Я також повинен зазначити, що я не ставлю ідентифікатори на таблиці зв’язків / об'єднань, лише на таблиці, що містять дані.
JeeBee

3

Я шукаю природні первинні ключі та використовую їх там, де можу.

Якщо природних ключів не знайти, я віддаю перевагу GUID перед INT ++, оскільки SQL Server використовує дерева, і погано завжди додавати ключі до кінця в деревах.

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

Оскільки мені пощастило використовувати SQL Server, я можу вивчити плани виконання та статистику за допомогою профайлера та аналізатора запитів та дізнатися, як мої ключі працюють дуже легко.


Чи є у вас документація для резервного копіювання цього твердження: "якщо ніяких природних ключів не знайти, я віддаю перевагу GUID INT ++, оскільки SQL Server використовує дерева, і погано завжди додавати ключі до кінця в деревах." Не скептично, просто намагаюся скласти якусь документацію.
Ллойд Коттен

1
@Lloyd - Радий, що ти захоплюєшся тим, що я вважаю себе дуже захоплюючим. Хороший вихідний пункт у msdn.microsoft.com/en-us/library/ms177443(SQL.90).aspx
Guge

2

Я завжди використовую поле для автонабору чи ідентичності.

Я працював для клієнта, який використовував SSN в якості основного ключа, а потім через положення HIPAA був змушений змінити на "MemberID", і це спричинило безліч проблем при оновленні іноземних ключів у відповідних таблицях. Дотримання послідовного стандарту стовпця особи допомогло мені уникнути подібної проблеми у всіх моїх проектах.


6
Поганий вибір природного ключа розробником не означає, що природні ключі погані.
Том Н

1
Важкий у використанні інструмент - це якось не суперечить цьому інструменту?
Sqeaky

1

Усі таблиці повинні мати первинний ключ. Інакше у вас є HEAP - в деяких ситуаціях це може бути саме те, що ви хочете (велике завантаження вставки, коли дані потім реплікуються через сервісного брокера в іншу базу даних або таблицю, наприклад).

Для таблиць пошуку з невеликим обсягом рядків ви можете використовувати код 3 CHAR в якості основного ключа, оскільки це займає менше місця, ніж INT, але різниця в продуктивності незначна. Крім цього, я б завжди використовував INT, якщо у вас немає довідкової таблиці, яка, можливо, має складений первинний ключ, складений із сторонніх ключів з пов'язаних таблиць.


1

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


1

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

Вам потрібно створити COMB GUID. Хороша стаття про це та статистику продуктивності - вартість GUIDs як первинних ключів .

Також деякий код для побудови COMB GUID в SQL міститься в Uniqueidentifier vs identitet ( архів ) .


5
ІМХО, орієнтири слід використовувати лише тоді, коли вам потрібно синхронізувати дані в базі даних. У якому автоматично створений ідентифікатор є проблематичним. Різниця між використанням довідника та використанням основного числового типу полягає в тому, що для отримання гіда знадобиться 16 байт на рядок, а числовий буде значно меншим.
Logicalmind

Якщо ви переходите за посиланням, яке я наводив вище, різниця у продуктивності за допомогою COMB Guids дуже мала.
Донні В.

0

Ми робимо багато приєднань, і складові первинні ключі щойно перетворилися на виступ. Простий int або long вирішує багато проблем, навіть якщо ви вводите другий ключ-кандидат, але приєднатись до одного поля проти трьох набагато простіше та зрозуміліше.


1
Ця стратегія розпадається, коли вам зараз доведеться пройти 6 таблиць, щоб приєднатись до фактичних двох таблиць, які вам потрібні, оскільки складові ключі не розповсюджувалися. Крім того, це вимагає використання петель / курсорів для декількох вставок, які можуть бути ВЕЛИЧЕЗНИМИ свинями.
Том Н

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

0

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

  • Ідентифікатор рядка (GUID)
  • Creator (рядок; має за замовчуванням ім'я поточного користувача ( SUSER_SNAME()у T-SQL))
  • Створено (DateTime)
  • Відмітка часу

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

Тим часом власне ПК - це, по можливості, природний ключ. Мої внутрішні правила - це щось на кшталт:

  • Люди - використовують сурогатний ключ, наприклад INT. Якщо вона внутрішня, GUID користувача Active Directory є прийнятним вибором
  • Таблиці пошуку (наприклад, StatusCodes) - використовувати короткий код CHAR; це легше запам'ятати, ніж INT, і в багатьох випадках паперові форми та користувачі також використовуватимуть його для стислості (наприклад, Status = "E" для "Термін дії", "A" для "Затверджено", "NADIS" для "Не визначено азбесту" У зразку ")
  • Зв'язування таблиць - комбінація ФК (наприклад EventId, AttendeeId)

Тож в ідеалі ви маєте природний, читабельний та запам'ятовуваний ПК, і дружній для ORM дружній посібник із одним ID на стіл.

Caveat: бази даних, які я підтримую, мають тенденцію до 100 000 записів, а не мільйонів чи мільярдів, тому якщо у вас є досвід більш великих систем, що протипоказано моїм порадам, сміливо ігноруйте мене!


1
Ви пропонуєте створити обидва GUID та INT СК для таблиць без сильного природного ключа?

Не потрібно, але переваги полягають у тому, що: а) це полегшує реплікацію, якщо вона вам потрібна; б) під час роботи з ORM ви можете призначити унікальний ідентифікатор своєму об'єкту в коді перед його збереженням (що корисно, якщо ви Ви повинні зробити багато редагування вашого об'єкта, можливо, зберегти його в кеш сесії, перш ніж зберегти його). Ключ - INT в цій інстанції; GUID - це лише бонус.
Кіт Вільямс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.