Каковы лучшие практики относительно таблиц поиска в реляционных базах данных?

14

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

Например, предположим, что у нас есть справочная таблица party(предназначенная для хранения информации о политических партиях), которая имеет два столбца:

  • party_code_idn, который содержит сгенерированные системой числовые значения и (без значения бизнес-области ) работает как суррогат для реального ключа.
  • party_code, является реальным или «естественным» ключом таблицы, потому что он поддерживает значения, имеющие коннотации бизнес-домена .

И допустим, что в такой таблице сохраняются следующие данные:

 +----------------+------------+
 | party_code_idn | party_code |
 +----------------+------------+
 |              1 | Republican |
 |              2 | Democratic |
 +----------------+------------+

party_codeКолонна, которая сохраняет значения «Республиканский» и «демократическая», будучи реальным ключом таблицы, устанавливается с ограничением UNIQUE, но необязательно , добавил party_code_idnи определил его как PK таблицы (хотя, говоря логически , party_codeможет работать как ПЕРВИЧНЫЙ КЛЮЧ [PK]).

Вопрос

Каковы лучшие методы для указания на значения поиска из таблиц транзакций ? Должен ли я установить ссылки FOREIGN KEY (FK) либо (a) непосредственно на естественную и значимую ценность, либо (b) для суррогатных значений?

Вариант (а) , например,

 +---------------+------------+---------+
 | candidate_idn | party_code |  city   |
 +---------------+------------+---------+
 |             1 | Democratic | Alaska  |
 |             2 | Republican | Memphis |
 +---------------+------------+---------+

имеет следующие свойства 1 :

  1. Читается для конечного пользователя (+)
  2. Легко импортировать-экспортировать через системы (+)
  3. Трудно изменить значение, так как оно требует модификации во всех ссылочных таблицах (-)
  4. Добавление нового значения не требует больших затрат (=)

Я думаю, что это почти как « передать по значению », провести аналогию из вызова функции на языке программирования приложений.

Вариант (б) , например,

 +---------------+----------------+---------+
 | candidate_idn | party_code_idn |  city   |
 +---------------+----------------+---------+
 |             1 |              1 | Alaska  |
 |             2 |              2 | Memphis |
 +---------------+----------------+---------+

имеет свойства ниже:

  1. Не читается для конечного пользователя (-)
  2. Сложно импортировать-экспортировать, так как нам нужно отменить ссылку на него (-)
  3. Легко изменить значения, так как мы храним ссылки только в таблицах транзакций (+)
  4. Добавление нового значения не требует больших затрат (=)

Это очень похоже на « передачу по ссылке », если сравнивать с вызовом функции на языке программирования приложения.

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

1. Обратите внимание , что +, -и =указывают на преимущество этих свойств.

Вопрос

Очень важно: есть ли разница между таблицей поиска (или кодом ) и ссылкой на FK, если мы просто собираемся использовать последний подход? Я думаю, что они работают точно так же.

Связанные ресурсы

Nishant
источник

Ответы:

10

К IDN, я понимаю , что вы означаете IDENTITY, SEQUENCEили AUTO_INCREMENTполе? Вы должны посмотреть здесь и здесь .

Обратите внимание, раздел 5 (Неправильное использование значений данных в качестве элементов данных) первой ссылки под рисунком 10

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

Итак, этот эксперт считает, что вам следует «почитать» суррогатные ключи. Это действительно довольно простой метод SQL и не должен вызывать проблем в вашем повседневном SQL. Похоже, что на рисунке 10 есть ошибка - sales_person в SalesData должен быть суррогатным ключом (т.е. числом), а не текстом. Я понял это из цитаты выше.

Чего следует избегать любой ценой, так это соблазна (очень распространенного для начинающих программистов баз данных) совершить ошибку, описанную в разделе (1) Common Lookup Tables. Это обычно называется подходом MUCK (Massive Unified Code Key ) (не случайно :-), особенно Джо Селко , также саркастически известным как OTLT - One True Lookup Table ), и приводит к всевозможным трудностям. Начинающие программисты, похоже, считают, что один код / ​​поиск / любая таблица «чище» и будет более эффективным, когда ничто не может быть дальше от истины.

Из второй ссылки выше:

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

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

Verace
источник
Под IDN я подразумевал автоматически сгенерированный внешний ключ. Я не использую Common Lookup Tables, не уверен, как вы думаете, я использовал это? На самом деле мы используем сотни таблиц кодов. Кажется действительно странным, что кто-то сделал бы это в единой таблице. Но хорошо знать, что такая модель существует и ее следует избегать. EAV кажется интересным. Таким образом, консенсус заключается в том, что я должен разыменовать, используя IDN, то есть суррогатный ключ?
Нишант
1
Стратегия разыменования, безусловно, является подходом большинства. Почему бы не немного поэкспериментировать и посмотреть, как вы ладите? Выберите некоторые естественные ключи и посмотрите, как работает ваш SQL - затем укажите суррогат и поэкспериментируйте с ним некоторое время. Celko и Pascal будут пользоваться уважением в мире SQL / Relational, но я видел, как люди спорили с ними, говоря, что их подход слишком доктрина и пурист - и что в "реальных" системах должны использоваться суррогатные ключи. Если ваш естественный ключ состоит из трех полей, и он находится FOREIGN KEYв другой таблице, он может быть довольно грязным, но YMMV.
Верас
Да, я подумал об этом пуристе, и я подумал, почему люди используют суррогатные ключи! И тогда некоторые случаи использования казались действительно сложными в пуристическом мире. Я чувствовал, что суррогатный подход проще, хотя у вас есть некоторые недостатки при импорте и экспорте. Действительно, сценарий комбинации может быть сложнее. Кстати, таблицы кодов мало чем отличаются от внешнего ключа в суррогатном сценарии, верно? Я имею в виду, что существует логическое различие, но это не что иное, как внешний ключ.
Нишант
1
Вы можете применять свои естественные ключи с помощью UNIQUE CONSTRAINTs и NOT NULLs - ну, ваши записи в таблице кодов находятся FOREIGN KEYв таблицах, которые используют / ссылаются на них - поэтому понятия связаны, но не совпадают. Суррогатный ключ таблицы кодов - это поле, которое появляется в «дочерней» таблице - конечно, оно менее разборчиво, но INTне очень большое - не требуется много места, что является преимуществом суррогатных ключей.
Верас
10

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

Idn: 1
Name: Democrats
Code: D      (or DEM)

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

Этот стиль был назван аббревиатурой. Я могу рекомендовать письмо Селко по этому вопросу. Google книги содержит несколько примеров. Поиск "Celko кодирования".

Другие примеры: 2- или 3-буквенное кодирование для стран, 3-буквенное кодирование (GBP, USD, EUR) для кодов валют. Коротко, самоочевидно и не меняется (и для них есть ISO).

Майкл Грин
источник