Сурогат проти природних / ділових ключів [закрито]


174

Ось ми знову, старий аргумент все ще виникає ...

Чи краще нам мати бізнес-ключ в якості основного ключа, чи краще мати сурогатний ідентифікатор (тобто ідентифікатор SQL Server) з унікальним обмеженням у полі бізнес-ключа?

Надайте, будь ласка, приклади чи докази на підтвердження вашої теорії.


24
@Joachim Sauer: Аргумент про те, чи є суб'єктивна річ, може бути сам суб'єктивним, без цього жодним чином стосується об'єктивності чи суб'єктивності речі, про яку йдеться. Якщо ви не готові вказати точні об'єктивні критерії, які роблять щось об'єктивним. Є речі, які називаються "відкритими поняттями", наприклад, скільки волосків потрібно, щоб зробити бороду. Можна об'єктивно сказати, що людина без волосся на підборідді не має бороди, а у людини, що має 5000 волосків на дюйм, має бороду, але десь посередині суб'єктивне судження потрібно для об'єктивного визначення.
ЕрікЕ

@Manrico: ти просто повинен запитати себе в цьому: якщо я не використовую сурогатний ключ, чи буде мій основний ключ все-таки непорушним? Якщо відповідь "ні", то слід серйозно розглянути можливість використання сурогатного ключа. Крім того, якщо первинний ключ складається частково з даних користувачів, слід розглянути можливість використання сурогатного ключа. Чому? Через небезпеку аномалій даних.
code4life

@TylerRick Але це не зовсім вдале питання. Він просить рішення, яке, як правило, застосовується у всіх ситуаціях, коли явно не існує жодного, як це підтверджує "релігійна війна", про яку прекрасно знає запитувач (цитата: "Ось ми знову, старий аргумент все ще виникає. .. "). Замість того, щоб замислюватися про те, чи змінився світ і, нарешті, було надано вагому причину вибору однієї сторони весь час, краще продовжувати задавати це питання знову і знову для кожної конкретної ситуації, і публікувати повідомлення, коли ви не впевнені. . Це просто викликає догматизм.
MarioDS

Відповіді:


97

І те й інше. Поставте торт і з'їжте його.

Пам'ятайте, що в первинному ключі немає нічого особливого, крім того, що він позначений як такий. Це не що інше, як НЕ НУЛЬНЕ УНІКАЛЬНЕ обмеження, а таблиця може мати більше одного.

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


7
Якщо у вас є кілька "кандидатських" ключів (поля або колекції однакових розмірів полів, які НЕ НУЛЬНІ УНІКАЛЬНІ), ви, ймовірно, порушите нормальну форму Бойса-Кодда. BCNF перевищує 3NF, тому мало хто переживає про це. Однак є ситуації, коли перебування в БКНФ є дуже корисним.
Алан

2
Домовились. Справжнє запитання повинно бути таким: чи варто додати до моїх таблиць унікальний сурогатний ключ? Зовсім інше питання - що використовувати для логічного первинного ключа. Вони по суті є лише ненульовими унікальними обмеженнями індексу.
dkretz

1
"Кожна проблема вирішується з іншим рівнем
непрямості

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

2
Це більше, ніж НЕ НУЛЬНЕ УНІКАЛЬНЕ обмеження. Первинний ключ використовується як кластерний індекс, який визначає фізичний порядок ваших даних. Взагалі Integer легко збалансувати, оскільки він збільшується послідовно, і ваші дані додаватимуться до EOF на диску. Якщо ви використовуєте менш послідовні дані, такі як текст або GUID (UUID), буде набагато більше дискового вводу-виводу та зусиль, щоб збалансувати індекс, я вважаю, що це велика різниця
Jin

124

Лише кілька причин використання сурогатних ключів:

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

  2. Конвенція : Дозволяє мати стандартизований стовпчик основного імені, призначений для імен, а не думати про те, як з'єднати таблиці з різними іменами для своїх ПК.

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


2
Тепер, прочитавши багато про сурогатні ключі та природні ключі, я думаю, що краще використовувати сурогатні ключі. Але в моїй базі даних природні ключі (NVARCHAR (20)) повинні бути унікальними. Я не розумію, як я можу отримати більшу швидкість, якщо мені потрібно перевірити всі дані в цьому стовпці, щоб не повторювати жодне значення (використовуючи обмеження NOT NULL UNIQUE) на кожній вставці.
VansFannel

70

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

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

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

проти:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

Якщо хтось серйозно не вважає, що наступне - це добра ідея?

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Але" хтось скаже ", що станеться, коли зміниться код MYPROJECT або VALID або HR?" На що моя відповідь буде: "навіщо вам потрібно це міняти?" Це не "природні" ключі в тому сенсі, що деякі сторонні органи збираються прийняти законодавство про те, що відтепер "VALID" має бути перекодовано як "ДОБРО". Лише невеликий відсоток "природних" ключів дійсно підпадає під цю категорію - звичайні приклади SSN та поштовий індекс. Я б неодмінно використовував безглуздий цифровий ключ для таблиць на зразок Person, Address - але не для всього , про що чомусь більшість людей тут, схоже, виступає.

Дивіться також: моя відповідь на інше питання


14
-1 Природні ключі як первинний ключ мають проблему, що для кожної дочірньої таблиці ви повинні додати батьківський ключ, який може складатися з більш ніж одного поля (замість того, щоб це було лише сурогатним ключем), а також дитиною ключ. Тож уявіть собі наступне, де починаючи з TABLEA відносини дорівнюють 1-0 .. *: TABLEA PK: ID_A TABLEB PK: ID_A ID_B TABLEC PK: ID_A ID_B ID_C TABLED PK: ID_A ID_B ID_C ID_D. Бачите проблему? Батьківський ключ поширюється в дочірніх таблицях. Що буде, якщо зміниться первинний ключ TABLEA? Тепер вам доведеться переробляти всі дочірні таблиці ПК.
Альфредо Озоріо

9
@Alfredo: так, звичайно, є компроміс. Однак за свій 20-річний досвід я рідко бачив визначення зміни ПК у таблиці. Якби це відбувалося регулярно, я, мабуть, уникав і природних ключів. Насправді, в надзвичайно рідкісних випадках, коли це трапляється, я готовий прийняти удар від розширеного удару.
Тоні Ендрюс

10
Я не погоджуюсь. Часто трапляються випадки, коли хтось із зовнішніх органів (замовника) законодавчо визначає, що природний ключ потребує редагування, а отже, розповсюдження у всій системі. Я бачу, що це відбувається регулярно. Єдиний спосіб ви можете бути впевнені, що ключ ніколи не потрібно буде змінювати, коли він за визначенням безглуздий. Крім того, сучасні бази даних обробляють внутрішнє з'єднання надзвичайно ефективно, тому потенційно великі вигоди від використання сурогатів, як правило, переважають за перевагу не потрібно робити стільки внутрішніх з'єднань.
TTT

8
@TTT: Тоді дизайн був слабким для початку. Знову-таки, тут чоловіки відокремлюються від хлопців: роблячи правильний вибір, коли використовувати природний ключ, а коли використовувати сурогат. Ви вирішили, що за столом, не як загальна догма.
DanMan

7
Я також маю 20+ років досвіду, і я другий ваш погляд. Я колись створив сховище даних oracle з сурогатними ключами, і підтримка даних була як пекло. Ви просто ніколи не можете безпосередньо отримати доступ до своїх даних. Вам завжди потрібно писати запити на все, і це робить сурогатні ключі просто жахливими для обробки.
SQL Police

31

Сурогатний ключ НІКОЛИ не матиме причин змінюватися. Я не можу сказати те саме про природні ключі. Прізвища, адреси електронної пошти, номерні номери ISBN - всі вони можуть змінюватися за один день.


31

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

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

Мислите компанії: ви щаслива компанія Merkin, яка працює з іншими компаніями в Merkia. Ви досить розумні, щоб не використовувати назву компанії в якості основного ключа, тому ви використовуєте унікальний ідентифікатор компанії Merkia в цілому 10 буквено-цифрових символів. Тоді Меркія змінює посвідчення компанії, оскільки вони думали, що це буде гарною ідеєю. Це нормально, ви використовуєте функцію каскадного оновлення db-двигуна для змін, які не повинні вас залучати в першу чергу. Згодом ваш бізнес розширюється, і тепер ви працюєте з компанією у Фредонії. Ідентифікатор компанії Freedonian має до 16 символів. Вам потрібно збільшити первинний ключ ідентифікатора компанії (також поля іноземних ключів у Замовленнях, Випусках, MoneyTransfers тощо), додавши поле "Країна" у первинний ключ (також у закордонних ключах). Ой! Громадянська війна у Фредонії, з розколом на три країни. Ім'я країни вашого партнера слід змінити на нове; каскадні оновлення на допомогу. До речі, який ваш основний ключ? (Країна, CompanyID) або (CompanyID, країна)? Останній допомагає приєднатися, перший уникає іншого індексу (або, можливо, багатьох, якщо ви також хочете, щоб ваші замовлення були згруповані по країні).

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


Ви виграєте всі інтернети найкрутішим виглядом імені користувача!
Ієн Холдер

1
Це майже що таке суперечка: "Я не згоден з цим".
jcollum

5
Підказка стрілки вниз говорить "Ця відповідь не корисна", а не "Я не згоден з цим". Можливо, у цій конкретній відповіді значення є близькими, але вони, як правило, не однакові.
tzot

1
Якщо хтось вважає, що ваша відповідь неправильна, то він (/ вона) також подумає, що вона веде запитувача в неправильному напрямку (навпроти правильного напрямку), і тому буде вважати вашу відповідь ще гіршою, ніж "недоброзичлива", обґрунтовуючи в своєму (/ її) розуміх протизаконний рух.
Ервін Смоут

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

25

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

Ось мої причини:

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

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

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

  4. В одній до багатьох ланцюжків відносин логічні брелоки. Так, наприклад, в організацій є багато облікових записів, а на рахунках - багато рахунків-фактур. Отже, логічним ключем організації є OrgName. Логічний ключ облікових записів - OrgName, AccountID. Логічним ключем рахунка-фактури є OrgName, AccountID, InvoiceNumber.

    Якщо використовуються сурогатні ключі, брелоки обрізаються лише наявністю стороннього ключа для безпосереднього батьків. Наприклад, у таблиці рахунків-фактур немає стовпця OrgName. У ньому є лише стовпець для облікового записуIDID. Якщо ви хочете шукати рахунки-фактури для певної організації, вам потрібно буде приєднатися до таблиць "Організація", "Рахунок" та "Рахунок-фактура". Якщо ви використовуєте логічні клавіші, ви можете безпосередньо запитувати таблицю організації.

  5. Зберігання сурогатних ключових значень таблиць пошуку призводить до того, що таблиці заповнюються безглуздими цілими числами. Для перегляду даних необхідно створити складні представлення даних, які приєднуються до всіх таблиць пошуку. Таблиця пошуку призначена для вміщення набору прийнятних значень для стовпця. Він не повинен бути кодифікований, зберігаючи натомість цілий сурогатний ключ. У правилах нормалізації немає нічого, що б запропонувало зберігати сурогатне ціле число замість самого значення.

  6. У мене є три різні книги баз даних. Жодна з них не показує використання сурогатних ключів.


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

26
-1: Я написав і підтримував десятки заявок. Ті, у кого найбільше проблем, пов'язаних з даними, були ті, хто використовує природні ключі.
Сокіл

6
Деякі ваші пункти припускають, що сурогатним ключем повинен бути ПК або повинен бути стовпчиком, що кластеризується - неправда. Ваші пункти 1 і 5 ігнорують той факт, що цілі числа - це 4 байти, а природних ключів майже завжди багато, набагато більше байтів. І кожен некластеризований індекс повинен повторювати байти тих природних ключів, які знаходяться в кластерному індексі, тому таблиці та індекси у вашій базі даних із природними ключами матимуть набагато менші рядки на сторінці, що означає набагато гіршу ефективність читання , що робить запити повільнішими , а не швидшими.
ЕрікЕ

3
Ще одна причина проти природних ключів (приклади: атомні номери, VIN тощо) може змінити логіку бізнесу, що збільшує тип даних. Наприклад: До: Відстеження зарядів атомів, Після: Відстеження зарядів атомів та сполук. Перед: Відстеження автотранспорту на предмет вантажопідйомності. Після: Додавання літаків, катерів, велосипедів та людей для вантажопідйомності.
forforf

3
Я думаю, у вас немає таблиць, де первинний ключ складається частково навіть з 1) будь-якого атрибута, який може і змінюється), або 2) з введення користувачем (наприклад, динамічно генеровані списки пошуку). Якщо ви не можете гарантувати незмінність ключів, вам доведеться оновити всі ці зв’язки сутності за допомогою коду або сценаріїв "виправити" вручну. Якщо вам ніколи цього не доводилося робити ... я думаю, ваша база даних є сурогатною без ключа і ... незвичною.
code4life

18

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

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

Недоліки сурогатних ключів

Сурогатними ключами є:

  1. Джерело проблем із роботою:
    • Зазвичай вони реалізуються за допомогою стовпців з автоматичним збільшенням, що означає:
      • Повернення до бази даних кожного разу, коли ви бажаєте отримати новий Id (я знаю, що це можна покращити за допомогою кешування або [seq] hilo подібних алгоритмів, але все ж у цих методів є свої недоліки).
      • Якщо вам потрібно перенести свої дані з однієї схеми на іншу (це трапляється досить регулярно в моїй компанії, принаймні), то у вас можуть виникнути проблеми зіткнення Id. І так, я знаю, що ви можете використовувати UUID, але для цього потрібно 32 шістнадцяткових цифр! (Якщо ви дбаєте про розмір бази даних, то це може бути проблемою).
      • Якщо ви використовуєте одну послідовність для всіх своїх сурогатних ключів, то, напевно, - ви закінчитеся суперечками у вашій базі даних.
  2. Схильний помилятися. Послідовність має обмеження максимальної цінності, тому - як розробник - ви повинні звернути увагу на такі моменти:
    • Ви повинні провести цикл своєї послідовності (коли буде досягнуто максимальне значення, воно повернеться до 1,2, ...).
    • Якщо ви використовуєте послідовність як упорядкування (з часом) своїх даних, тоді вам слід обробити випадок перемикання (стовпець з Id 1 може бути новішим, ніж рядок із значенням Id max - 1).
    • Переконайтеся, що ваш код (і навіть ваш клієнтський інтерфейс, який не повинен відбуватися, оскільки він повинен бути внутрішнім Id) підтримує цілі числа 32b / 64b, які ви використовували для зберігання значень послідовності.
  3. Вони не гарантують не дублюються дані. Ви завжди можете мати 2 ряди з усіма однаковими значеннями стовпців, але з іншим генерованим значенням Для мене це ТО проблема сурогатних ключів від проектної бази даних точки зору.
  4. Детальніше у Вікіпедії ...

Міфи про природні ключі

  1. Складові ключі менш неефективні, ніж сурогатні ключі. Немає! Це залежить від використовуваного двигуна бази даних:
  2. Природні ключі не існують у реальному житті. Вибачте, але вони існують! Наприклад, в авіаційній галузі наступний кортеж буде завжди унікальним щодо даного регулярного рейсу (авіакомпанія, дата вильоту, дата польоту, номер експлуатації). Більш загально, коли набір бізнес-даних гарантовано є унікальним за даним стандартом, то цей набір даних є [добрим] природним ключовим кандидатом.
  3. Природні ключі "забруднюють схему" дочірніх таблиць. Для мене це скоріше почуття, ніж реальна проблема. Наявність 4-х стовпчиків первинного ключа по 2 байти може бути ефективнішим, ніж один стовпець із 11 байтів. Крім того, 4 стовпці можна використовувати для запиту дочірньої таблиці безпосередньо (використовуючи 4 стовпці в пункті де), не приєднуючись до батьківської таблиці.

Висновок

Використовуйте природні ключі, коли це доречно, і використовуйте сурогатні ключі, коли краще їх використовувати.

Сподіваюся, що це комусь допомогло!


3
Що відбувається, коли дата перельоту запланованого рейсу перенесена? Чи потрібно відстежувати всі пов’язані об'єкти та видаляти ключі, чи ви фактично оновлюєте всі ключі у відповідних об'єктах? Або ви маєте справу з простою, єдиною таблицею (можливо, навіть не 3NF)?
code4life

Відмінна точка @ code4life
forcewill

@ code4life: саме тут вскакує OperaSuffix. Для того, щоб зберегти той же політ номер, щоб уникнути плутанини клієнтів, ми додамо лише суфікс (наприклад, "D").
mwnsiri

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

15

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

EDIT: Я намагався знайти посилання на нього в Інтернеті, але не зміг. Однак у «Шаблонах архітектури підприємства» [Фоулер] є добре пояснення того, чому ви не повинні використовувати нічого, крім ключа, не має іншого значення, крім ключа. Це зводиться до того, що вона повинна мати одну роботу і одну роботу.


22
У Мартіна Фаулера може бути багато речей, але він не є авторитетом у розробці баз даних.
Тоні Ендрюс

Я думаю, вам слід надати певні міркування, перш ніж дійти висновку.
Арне Евертссон

4
@ArneEvertsoon Причина там. "Це зводиться до того, що у нього повинна бути одна робота і одна робота". Єдина відповідальність.
Ієн Холдер

10

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

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

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

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


6

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

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


1
На жаль, у автомобілів є природний ключ, який не змінюється: VIN (принаймні, в Америці ...)
jcollum

@jcollum Так, це справедливо. Моя думка все ще стоїть, хоча мій приклад був не обов'язково таким хорошим, як міг би бути.
Марк Embling

2
Список мов може бути прикладом природного ключа, коли ви базуєте його на ISO-кодах. Тож якщо ви тоді хотіли завантажити вміст із таблиці певною мовою, вам не потрібно було б приєднуватися до languagesтаблиці, оскільки код мови (ID) вже є в textsтаблиці.
DanMan

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

5

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

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

Бізнес-логіка / природні ключі можуть змінюватися, але фізичний ключ таблиці НІКОЛИ не повинен змінюватися.


4

За сценарієм сховища даних, я вважаю, що краще дотримуватися сурогатного ключового шляху. Дві причини:

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

2

Сурогатні ключі можуть бути корисними, коли інформація про бізнес може змінюватися або бути ідентичною. Зрештою, назви підприємств не повинні бути унікальними для всієї країни. Припустимо, ви маєте справу з двома підприємствами на ім’я Smith Electronics, одним у штаті Канзас та одним у штаті Мічиган. Ви можете відрізнити їх за адресою, але це зміниться. Навіть держава може змінитися; що робити, якщо Smith Electronics з Канзас-Сіті, штат Канзас рухається через річку до Канзас-Сіті, штат Міссурі? Немає очевидного способу відрізнити цей бізнес від природної ключової інформації, тому сурогатний ключ дуже корисний.

Подумайте про сурогатний ключ, як номер ISBN. Зазвичай ви ідентифікуєте книгу за назвою та автором. Однак у мене є дві книги під назвою "Перл-Харбор" від HP Willmott, і вони, безумовно, різні книги, а не просто різні видання. У такому випадку я міг би посилатися на зовнішній вигляд книг, або раніше, ніж на більш пізній, але це так само добре, що я маю відмовитися від ISBN.


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

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

@Christopher Cashell - натрапив на цю посаду ще рік тому, але я думав щось додати. Не гарантується, що ISBN є унікальним і може мати копії. У мене є друг, який працював у бібліотеці протягом багатьох років, і вони часто натрапляли на книги з дублікатами ISBN. Проблема полягає в тому, що унікальність ISBN належить до видавця, а не до одного органу, який гарантує, що всі номери для всіх видань є унікальними, і ті видавці не завжди мали спільний акт.
Томас

2
Прийшов на цю посаду ще рік тому і хотів зазначити, що ISBN насправді є природними ключами. Існує сенс, закладений у саме ключове значення, на відміну від сурогатного ключа. Наприклад, частина ключа ідентифікує видавця. Крім того, як я вже згадував вище, вони не гарантовано є унікальними. Вони повинні бути унікальними, але ця унікальність походить від видавців, і вони не завжди були ідеальними.
Томас

Технічно корпорації не можуть переміщатися між державами; Що відбувається, це те, що в новій державі створюється нова корпорація, а активи передаються. Це працює і для інформації бази даних.
Warren Dew

2

Нагадування - це недобра практика розміщувати кластерні індекси на випадкових сурогатних ключах, тобто GUID, які читають XY8D7-DFD8S, оскільки вони SQL Server не мають можливості фізично сортувати ці дані. Натомість слід розміщувати на цих даних унікальні індекси, хоча це може бути також вигідним просто запустити SQL-профайлер для основних операцій з таблицею, а потім розмістити ці дані в Раднику з налаштування бази даних.

Дивіться тему @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be


Я впевнений, що SQL Server може сортувати GUID.
Майкл Грін

Це не точно, хоча вони можуть оцінити GUID, одержаний сорт не є чутливим для людини. stackoverflow.com/questions/7810602/…
Брайан Лебедь

1
Справжнє твердження, але зовсім інше, ніж "SQL Server не має можливості їх фізично сортувати".
Майкл Грін

2

Випадок 1: Ваша таблиця - це таблиця пошуку містить менше 50 типів (вставок)

Використовуйте ділові / природні ключі . Наприклад:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Випадок 2: Ваша таблиця - це таблиця з тисячами вставок

Використовуйте сурогатні / автоматичні ключі . Наприклад:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

У першому випадку:

  • Ви можете вибрати всіх програмістів у таблиці PEOPLE без використання приєднання до таблиці JOB, але просто за допомогою: "SELECT * OF OF People OF WHERE JOBCODE = 'PRG'"

У другому випадку:

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

2

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


1

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

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

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

Більшість традиційних розробників PL / SQL, з якими я працював, не любили сурогатних ключів через кількість таблиць за приєднання, але наші тестові та виробничі бази ніколи не піднімали потужність; додаткові приєднання не вплинули на продуктивність програми. Діалекти бази даних, які не підтримують пункти типу "X внутрішнє з'єднання Y на Xa = Yb", або розробники, які не використовують цей синтаксис, додаткові з'єднання для сурогатних ключів роблять запити складнішими для читання, і довше набирати та перевірити: див. пост @ Тоні Ендрюса. Але якщо ви використовуєте ORM або будь-яку іншу структуру покоління SQL, ви цього не помітите. Сенсорне введення також пом'якшує.


Також; якщо ви хочете по-справжньому доїхати додому, що сурогатні ключі є саме цим, запускайте їх з випадкової великої кількості та збільшуйте послідовності на 3+, а не на 1. Або використовуйте ту саму послідовність, щоб генерувати значення для більше одного ключа.
WillC

1

Можливо, не зовсім відповідна цій темі, але головний біль у мене стосується сурогатних ключів. Попередньо поставлена ​​аналітика Oracle створює автоматично створені СК на всіх своїх таблицях розмірів на складі, а також зберігає дані за фактами. Таким чином, у будь-який час їх (розміри) потрібно перезавантажувати, додаючи нові стовпці або потрібно заповнювати їх для всіх елементів у параметрі, а SK, призначені під час оновлення, виключає СК із синхронізації з початковими значеннями, збереженими на факт, примушуючи повне перезавантаження всіх таблиць фактів, які до нього приєднуються. Я вважаю за краще, щоб навіть якщо SK був безглуздим числом, це був би спосіб, який він не міг би змінити для оригінальних / старих записів. Як багато хто знає, нестандартне рідко задовольняє потреби організації, і нам доводиться постійно налаштовувати. Зараз у нас на складі є дані на 3 роки, і повне перезавантаження з систем Oracle Financial дуже велике. Тож у моєму випадку вони не генеруються при введенні даних, а додаються на складі, щоб допомогти звітувати про ефективність. Я розумію, але наше змінюється, і це кошмар.


0

У випадку з базою даних про момент часу найкраще поєднувати сурогатні та природні ключі. наприклад, вам потрібно відслідковувати інформацію про члена клубу. Деякі атрибути члена ніколи не змінюються. наприклад, дата народження, але ім'я може змінюватися. Тож створіть таблицю учасників із сурогатним ключем member_id та створіть стовпчик для DOB. Створіть іншу таблицю з назвою імені людини та створіть стовпці для member_id, member_fname, member_lname, date_update. У цій таблиці природним ключем буде member_id + date_update.

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