Нужны ли этим конкретным таблицам суррогатные ключи?


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 , который можно увидеть на международных досках обмена валют.

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

Вопросов

Достаточно ли хороши эти натуральные ПК?

Является ли использование всемирно признанных стандартов, которые принимаются целыми отраслями, достаточно хорошо для ПК?

Нужны ли этим таблицам суррогаты, несмотря ни на что?

Ответы:


15

Нет, они не Эти ключи, безусловно, достаточно хороши!

Они уникальны, не редко меняются и значимы , что является шагом вперед по сравнению с суррогатным ключом. Это в значительной степени определение хорошего ПК.

Ограничения на то, что PK являются неизменяемыми и числово-целочисленными, не являются частью реляционной модели (Codd) или какого-либо стандарта SQL (ANSI или другого).


3
Первичные ключи также должны быть неизменяемыми, а коды аэропортов IATA определенно не являются. Они могут быть изменены по желанию IATA.
Джеймс Снелл

3
@JamesSnell - Коды аэропортов IATA примерно такие же неизменные, как и коды стран. Вы говорите об изменениях, может быть, раз в десять лет, если это так. Смотрите здесь для обсуждения этого вопроса. Есть много устаревших кодов, которые все еще на месте, потому что они слишком много проблем, чтобы изменить. Кроме того, для этого и нужно обновление CASCADE. Изменяемые первичные ключи являются законными, если не большой практикой.
Бобсон,

2
@EricKing Эти третьи стороны, как правило, состоят из представителей всех основных партий многих отраслей, затем стандарты обсуждаются годами, а затем голосуются, пока не будет достигнут разумный консенсус. Кроме того, они согласовывают механизмы, с помощью которых производится любое изменение или новое добавление. Кроме того, стандарты списков кодов создаются не по прихоти, а потому, что существует потребность в создании контролируемого, уважаемого, согласованного списка кодов для чего-либо, чтобы иметь возможность взаимодействовать по всему миру и правильно общаться по всему миру.
Тулаинс Кордова

2
@ user61852 - Можно сказать, что эти стандарты сделаны как первичные ключи.
Бобсон

3
@ Бобсон: «Есть много устаревших кодов, которые все еще существуют, потому что их слишком сложно изменить» -> возможно, потому что они являются первичными ключами?
Мацей

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              |
+-------------------------+

Другими словами, если только эти отраслевые стандартные коды не являются важными для моего приложения, я бы не использовал их в качестве PK моих таблиц. Они просто ярлыки. Большинство других моих таблиц, вероятно, в любом случае будут иметь суррогатные ключи, и эта настройка добавит согласованности в мою модель данных. Стоимость «добавления» суррогатных ключей минимальна.

Обновление на основе некоторых комментариев:

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

Однако, если таблица является просто справочной таблицей, которая используется в нескольких углах приложения, относительная важность кодов IATA может не оправдать столь заметное место в инфраструктуре базы данных. Конечно, вам, возможно, придется сделать дополнительное объединение в нескольких запросах здесь и там, но эти усилия могут быть тривиальными по сравнению с усилиями, которые потребуются для проведения исследования, чтобы гарантировать, что вы полностью понимаете последствия создания кодов IATA поле первичного ключа. В некоторых случаях мне не только все равно, но я не хочу заботиться о кодах IATA. Приведенный ниже комментарий @James Snell является прекрасным примером того, что мне, возможно, не захочется беспокоиться о влиянии на PK моих столов.

Также важна последовательность в дизайне. Если у вас есть база данных с десятками таблиц, которые все имеют согласованные суррогатные ключи, а затем несколько таблиц поиска, которые используют сторонние коды в качестве PK, это вносит несоответствие. Это не так уж и плохо, но требует дополнительного внимания в документации и такого, что не может быть оправдано. Ради бога, они справочные таблицы , просто использовать суррогатный ключ для согласованности - это прекрасно.

Обновление на основе дальнейших исследований:

Ладно, меня немного поразило любопытство, и я решил поинтересоваться кодами аэропортов IATA, начав со ссылок, приведенных в вопросе.

Как оказалось, коды IATA не так универсальны и авторитетны, как их ставит вопрос. Согласно этой странице :

Большинство стран используют четырехзначные коды ИКАО , а не коды ИАТА, в своих официальных авиационных публикациях.

Кроме того, коды IATA и коды ICAO отличаются от кодов идентификаторов FAA , которые являются еще одним способом идентификации аэродромов.

Моя точка зрения в том, чтобы поднять их, состоит не в том, чтобы начать дискуссию о том, какие коды лучше или более универсальны, более авторитетны или более полны, а именно, чтобы показать, почему разработка структуры вашей базы данных с произвольным идентификатором третьей стороны - это не то, что я бы выбрал делать , если не было конкретной бизнес-причины для этого .

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


1
То есть стандарты IATA достаточно хороши для авиакомпаний, но не для вас?
Тулаинс Кордова

1
Конечно, вам придется присоединиться к столу в аэропорту, если вы хотите искать багаж из лондонского аэропорта Хитроу, потому что вы не можете этого сделать select * from baggage where airport_code = 'LHR', то есть база данных может использоваться только через приложение, которое является очень узким и закрытым. подход, особенно когда владелец бизнеса тот, кто заплатил за базу данных и, следовательно, владеет ею. Также вам нужно будет написать код для выполнения повседневных задач, таких как импорт данных из одной базы данных в другую, чтобы избежать коллизий PK.
Тулаинс Кордова

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

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

2
@ user61852 - просто потому, что это стандартные коды, не означает, что система авиакомпаний использует их в качестве PK (может быть, у вас есть больше информации здесь?). Каскадное обновление в таком огромном масштабе кажется очень плохой идеей.
Джеффо

1

Хотя наличие суррогатных ключей на полях - это хорошо, и в этом нет ничего плохого, но что-то, что следует учитывать, может быть сам размер страницы индекса.

Поскольку это реляционная база данных, вы будете выполнять множество объединений, а наличие суррогатного ключа числового типа может упростить обработку базы данных, т. Е. Размер страницы индекса будет меньше и, следовательно, быстрее будет выполняться поиск. Если это небольшой проект, он не будет иметь значения, и вы без проблем обойдетесь, однако, чем больше будет приложение, тем больше вы захотите уменьшить узкие места.

Наличие типа данных BIGINT, INT, SMALLINT, TINYINT или любого целочисленного типа может избавить вас от проблем в будущем.

Просто мои 2 цента

ОБНОВИТЬ:

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

Крупный проект - ежедневно используют тысячи, десятки тысяч, миллионы пользователей. То, что вы бы создали для национальной / международной компании с огромной базой пользователей.

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

Если используется VARCHAR, это означает, что интервал не является равномерным, если только данные не всегда имеют одинаковую длину (в этом случае значение CHAR является более эффективным). Это замедляет поиск в индексе, и, поскольку сервер уже занят обработкой тысяч и тысяч запросов в секунду, теперь приходится тратить время на неоднородный индекс и снова делать то же самое с соединениями (что медленнее, чем регулярные выборки в неоптимизированной таблице, в качестве примера возьмем DW, где имеется как можно меньше соединений для ускорения поиска данных). Также, если вы используете UTF, который также может связываться с ядром базы данных (я видел несколько случаев).

Лично, из моего собственного опыта, правильно организованный индекс может увеличить скорость объединения на ~ 70%, а объединение с целочисленным столбцом может ускорить объединение примерно на ~ 25% (в зависимости от данных). , Поскольку основные таблицы начинают расти, и эти таблицы привыкнут к ним, вы бы предпочли, чтобы целочисленный тип данных занимал столбец с несколькими байтами по сравнению с полем VARCHAR / CHAR, который будет занимать больше места. Это сводится к экономии дискового пространства, повышению производительности и общей структуры реляционной базы данных.

Кроме того, как отметил Джеймс Снелл:

Первичные ключи также должны быть неизменяемыми, а коды аэропортов IATA определенно не являются. Они могут быть изменены по желанию IATA.

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


Это правильная мысль, но смысл этих таблиц в том, что в каждой таблице есть только конечное количество записей. Если вы на самом деле имели в виду размер кода small projectи bigger, пожалуйста, обновите, чтобы уточнить, почему это будет иметь значение.
Бобсон

1
Ограничения на то, что PK являются неизменяемыми и числово-целочисленными, не являются частью реляционной модели (Codd) или какого-либо стандарта SQL (ANSI или другого).
Тулаинс Кордова

4
Индексы, основанные на фиксированной длине, короткие строки (например, коды ISO) так же быстры, как и целые числа. Индексы основаны на переменной длине, длинные строки - нет.
Тулаинс Кордова

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

2
Присоединиться к спектаклю соломенный человек. Зачастую использование естественных ключей означает, что вам не нужно объединяться в первую очередь.
Майк Шеррилл 'Cat Recall'

1

Если вы используете подход «Я использую суррогатные ключи все время», вы можете обойти этот тип проблем. Это может быть не очень хорошо, потому что важно подумать о ваших данных, но это, безусловно, экономит много времени, энергии и усилий. Если кто-то и примет принятие этого правила, перечисленные примеры, безусловно, соответствуют требованиям, поскольку для внесения изменений требуется почти «акт конгресса».

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

Существуют некоторые случаи, характерные для США, где стандарты были радикально изменены: почтовый код расширился с 5 до 9 цифр, сокращения штатов до двух последовательных букв и избавились от периода (Помните, когда Иллинойс был болен?) И большинство мир должен иметь дело с Y2K. Если у вас есть приложение для работы в реальном времени с данными, разбросанными по всему миру, содержащим миллиарды записей, каскадные обновления - не лучшая идея, но не должны ли мы все работать в местах, сталкивающихся с такими проблемами? С этим набором данных вы можете проверить его сами и придумать более сложный ответ.


+1 Отличный ответ. Большую часть времени люди очень догматичны в этом вопросе. Многие разработчики баз данных имеют гигантское эго и считают себя владельцами базы данных и данных. Другие понимают, что владелец данных может использовать их только через определенное приложение, потому что он не может понять это. Они также предпочитают создавать условия для чего-то, что может произойти или не случиться в будущем, в то же время зарабатывая на жизнь адом из повседневных дел, таких как импорт данных и написание запросов. Также не в состоянии произвести какую-либо каноническую библиографию, которая поддерживает их точку зрения.
Тулаинс Кордова

Между прочим, правило «Я использую суррогатные ключи все время» не входит ни в реляционную модель (Кодса), ни в какой-либо стандарт SQL. Схема словаря данных Oracle использует естественные ключи, когда это возможно, и искусственные ключи в других случаях. PPDM ( ppdm.org ) также рекомендует смешанный подход и использует его в своей модели. Стандарт ANSI SQL ничего не говорит о суррогатах. Я думаю, что все-суррогаты и все-природные являются едкими. Некоторые естественные, а некоторые суррогатные - вот чему учит реляционная модель.
Тулаинс Кордова
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.