Чи потрібні ці конкретні таблиці сурогатних ключів?


13

Фон

У мене це таблиці

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_code string (PK) |  |country_code string (PK)|
|address string           |  |name string             |
|name  string             |  +------------------------+
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_code string (PK)|
|name string              |
+-------------------------+

airport_code - код аеропорту IATA (Міжнародна асоціація повітряного транспорту) , ви можете бачити їх у своїх багажних тегах під час подорожі літаком.

введіть тут опис зображення

country_code - стандартний код країни ISO 3166-1 A3 , їх можна побачити в олімпіадах.

введіть тут опис зображення

currency_code є Is0 417 стандартних 3 х символів коду валюти , ви можете побачити їх в міжнародних щитах обміну валют.

введіть тут опис зображення

Запитання

Чи є ці природні ПК досить хорошими?

Чи достатньо добре використовувати світові стандарти, які приймаються цілими галузями, для ПК?

Чи потрібні ці таблиці сурогати незалежно від того?

Відповіді:


15

Ні, вони ні. Ці клавіші, безумовно, досить хороші!

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

Обмеження щодо незмінності ПК та числових цілих чисел не є частиною реляційної моделі (Codd's) або будь-якого стандарту SQL (ANSI чи іншого).


3
Первинні ключі також повинні бути незмінними, чогось IATA-кодів аеропортів точно немає. Їх можна змінити за примхою IATA.
Джеймс Снелл

3
@JamesSnell - Коди аеропортів IATA приблизно такі ж незмінні, як і коди країн. Ви говорите про зміну, можливо, раз на десятиліття, якщо це так. Дивіться тут для обговорення цього питання. Існує багато застарілих кодів, які все ще існують, оскільки їх занадто багато проблем, щоб змінити. Крім того, саме для цього призначено оновлення CASCADE. Змінні первинні ключі є законними, якщо не чудовою практикою.
Бобсон

2
@EricKing Ці треті сторони, як правило, складаються з представників усіх основних партій багатьох галузей, тоді стандарти обговорюються роками, потім проголосують до досягнення розумного консенсусу. Також вони погоджуються з механізмами, за допомогою яких здійснюється будь-яка зміна чи нове доповнення. Крім того, стандарти кодових списків створюються не за примхою, а тому, що існує потреба у створенні контрольованого, поважаного, узгодженого, списку кодів для чогось, щоб мати можливість взаємодіяти в усьому світі та належним чином спілкуватися у всьому світі.
Tulains Córdova

2
@ User61852 - Можна сказати , що ці стандарти зроблені , щоб бути первинними ключами.
Бобсон

3
@Bobson: "Є багато застарілих кодів, які все ще існують, тому що у них занадто багато проблем, щоб змінити" -> можливо, тому що вони є первинними ключами?
Мацей

2

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

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

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_id       int (PK)|  |country_id     int (PK) |
|iata_airport_code string |  |iso_country_code string |
|icao_airport_code string |  +------------------------+
|faa_identifier    string |  
|address           string |  
|name              string |  
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_id int (PK)     |
|iso_currency_code string |
|name string              |
+-------------------------+

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

Оновлення на основі деяких коментарів:

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

Однак, якщо таблиця є лише таблицею пошуку, яка використовується в кількох куточках програми, відносна важливість кодів IATA може не виправдовувати такого помітного місця в інфраструктурі бази даних. Звичайно, можливо, вам доведеться зробити додаткове приєднання в декількох запитах тут і там, але це зусилля може бути банальним порівняно з зусиллями, необхідними для проведення досліджень, щоб гарантувати, що ви повністю розумієте наслідки внесення кодів IATA в поле первинного ключа. У деяких випадках мене не тільки не хвилює, але мені не хочеться піклуватися про коди IATA. Коментар @James Snell нижче - прекрасний приклад того, що я, можливо, не хотів би турбуватися про вплив на ПК моїх таблиць.

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

Оновлення на основі подальших досліджень:

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

Як виявляється, коди IATA не є настільки універсальними та авторитетними, як з'ясовує питання. Відповідно до цієї сторінки :

У більшості країн у своїх офіційних аеронавігаційних публікаціях використовуються чотиризначні коди ICAO , а не IATA.

Крім того, коди IATA та коди ICAO відрізняються від ідентифікаційних кодів FAA , які є ще одним способом ідентифікації аеродромів.

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

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


1
Отже стандарти IATA досить хороші для авіакомпаній, але не для вас?
Tulains Córdova

1
Звичайно, вам доведеться приєднатися аж до столу аеропорту, коли ви хочете шукати багаж з лондонського Хітроу, тому що ви цього не можете зробити select * from baggage where airport_code = 'LHR', це означає, що база даних може лише кинути додаток, що є дуже вузьким і власним підхід, особливо, коли власником бізнесу є той, хто заплатив за базу даних, і тому вона володіє нею. Крім того, вам доведеться писати код, щоб робити щоденні речі, такі як імпорт даних з однієї бази даних в іншу, щоб уникнути зіткнень ПК.
Tulains Córdova

1
Коди IATA не змінюються, тому їх не можна розглядати як кандидатів у ПК. Приклад: код IDL знаходився в Нью-Йорку, поки він не був перейменований в JFK. Код IDL зараз знаходиться в Міссісіпі.
Джеймс Снелл

2
@EricKing IATA та ISO дбають про те, щоб коди були досить стабільними, унікальними та загальновизнаними. Це багато в чому співпадає з інтересом людини, яка проектує стіл.
Тулен Кордова

2
@ user61852 - тому, що це стандартні коди, це не означає, що система авіакомпаній використовує їх як ПК (можливо, у вас тут більше розуміння?). Отримати каскадне оновлення в такому масштабному масштабі здається дуже поганою ідеєю.
JeffO

1

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

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

Наявність BIGINT, INT, SMALLINT, TINYINT або будь-якого цілого типу даних може врятувати вам певні проблеми в дорозі.

Всього мої 2 копійки

ОНОВЛЕННЯ:

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

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

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

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

Особисто, з мого власного досвіду, правильно організований індекс може збільшити швидкість з'єднання на ~ 70%, а виконання з'єднання в цілому стовпчику може прискорити приєднання приблизно на приблизно 25% (залежно від даних) . Оскільки основні таблиці починають зростати, і ці таблиці звикають до них, ви, швидше, матимете цілий тип даних, який займає стовпець, який має кілька байтів, а також поле VARCHAR / CHAR, яке займе більше місця. Це зводиться до економії місця на диску, підвищення продуктивності та загальної структури реляційної бази даних.

Також, як згадував Джеймс Снелл:

Первинні ключі також повинні бути незмінними, чогось IATA-кодів аеропортів точно немає. Їх можна змінити за примхою IATA.

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


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

1
Обмеження щодо незмінності ПК та числових цілих чисел не є частиною реляційної моделі (Codd's) або будь-якого стандарту SQL (ANSI чи іншого).
Tulains Córdova

4
Індекси на основі фіксованої довжини, короткі рядки (як ISO-коди) такі ж швидкі, як цілі числа. Індекси на основі змінної довжини, довгі рядки не є.
Tulains Córdova

Ось що я заявив (див. Частину VARCHAR vs CHAR вище), я не мав можливості перевірити короткий рядок з фіксованою довжиною проти числового цілого числа, але у мене був шанс зробити це зі змінною довжиною та цілим числом
Тоні Костелак

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

1

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

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

Є деякі випадки, характерні для США, де стандарти були кардинально змінені: Поштовий індекс розширився з 5 - 9 цифр, абревіатури штатів до послідовних 2 букв і позбувся періоду (пам'ятаєте, коли Іллінойс був хворий?), І більшість світ мав справу з Y2K. Якщо у вас є додаток у реальному часі з даними, розповсюдженими по всьому світу, що містять мільярди записів, каскадні оновлення - не найкраща ідея, але чи не варто ми всі працювати в місцях, які стикаються з такими проблемами? За допомогою цього набору даних ви можете перевірити його на собі і придумати більш різну відповідь.


+1 Відмінна відповідь. Здебільшого люди дуже догматичні щодо цього питання. Багато дизайнерів баз даних мають гігантське его та вважають себе власниками бази даних та даних. Інші бачать, що власник даних може використовувати їх лише через певний додаток, оскільки він не може мати сенс. Вони також вважають за краще передбачити щось, що може статися або не відбутися в майбутньому, роблячи пекельне життя, яке робиться щодня, наприклад, імпорт даних та написання запитів. Також не вдалося виготовити будь-яку канонічну бібліографію, яка б підтримувала їхню думку.
Тулен Кордова

До речі, правило "Я весь час використовую сурогатні ключі" немає ні в реляційній моделі (Codd's), ні в будь-якому стандарті SQL. Схема словника даних Oracle використовує природні ключі, коли це можливо, а штучні ключі в інших випадках. PPDM ( ppdm.org ) також рекомендує змішаний підхід і він використовує його у своїй моделі. Стандарт ANSI SQL нічого не говорить про сурогати. Я думаю, що сурогати і все природні є корозійними. Те, чому вчить реляційна модель, є деяким природним та сурогатним.
Тулен Кордова
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.