Почему использование является общей справочной таблицей для ограничения состояния объекта неправильно?

Согласно Пяти Простым Ошибкам Проектирования баз данных Необходимо Избежать Сенатором Anith, использование общей справочной таблицы для хранения возможных состояний для объекта является частой ошибкой.

Редактирование + Ответ: числа в статье Anith не хорошо маркированы - я думал, что и рисунок 1 и рисунок 2 являются примерами плохого дизайна, тогда как рисунок 2 является хорошим дизайном. Уф, волновался там на мгновение.

Таким образом:

  • Справочные таблицы: хороший.
  • Общие справочные таблицы: плохо.

Я сохраню свой вопрос ниже для ссылки.


Следующие причины приведены:

  1. "Вы теряете средства гарантировать точные данные; ограничения. Путем объединения различных объектов в единственную таблицу у Вас нет декларативных средств ограничить значения определенной категории".
    То, как ограничение оценивает, теряет точность?

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

  3. "Вы посвящаете себя жесткости и последующей сложности".
    Как?

  4. В-четвертых и наконец, Вы сталкиваетесь с физическими проблемами реализации.
    Я не вижу почему.

Я не соглашаюсь с большинством приведенных причин и хотел бы некоторый объективный критический анализ на своем неправильном? логика.

Мои примеры:

При приведении примера заданий в сервисе восстановления со многими возможными состояниями, которые обычно имеют естественный поток, давайте возьмем a JobStatus таблица:

  1. Зарегистрированный
  2. Присвоенный техническому специалисту
  3. Диагностирование проблемы
  4. Ожидание клиентского подтверждения
  5. Восстановленный и Готовый к Погрузке
  6. Repaired & Couriered
  7. Непоправимый и Готовый к Погрузке
  8. Отклоненная кавычка

Возможно, некоторые из этих состояний могут быть нормализованы к таблицам как Couriered Items, Completed Jobs и Quotes (с состояниями Pending/Accepted/Rejected), но это чувствует себя подобно ненужной сложности схемы.

Другой типичный пример был бы OrderStatus таблица для ограничения состояния порядка:

  1. Ожидание
  2. Завершенный
  3. Поставленный
  4. Отмененный
  5. Возмещенный

Заголовки состояния и описания находятся в одном месте для редактирования и легки к лесам как выпадающее с внешним ключом для динамических применений данных. Это работало хорошо на меня в прошлом. Если бизнес-правила диктуют создание нового статуса заказа, я могу просто добавить его к OrderStatus таблица, не восстанавливая мой код.

Почему это - плохая практика?


Редактирования: Я добавил причину Anith для своего вопроса и попытался остаться объективным.

--

23
задан casperOne 6 April 2012 в 17:01
поделиться

5 ответов

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

Это связано с тем, что:

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

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

править

Я вижу, вы отредактировали свой пост, чтобы процитировать все точки зрения Анит. Я думаю, что самый важный момент - это первый, касающийся ограничений.Если вы хотите ограничить столбец ORDERS.STATUS значениями из категории OrderStatus, вам потребуется отдельная таблица для принудительного применения внешнего ключа. Ваши альтернативы:

  • включить столбец CodeCategory в таблицу ORDERS и применить составной внешний ключ к общей таблице CODES, которой теперь нужен уникальный ключ (Категория, Код).
  • дублируют значения OrderStatus в проверочном ограничении
  • не применяют значения в базе данных и полагаются на раскрывающийся список приложения для ограничения значений.

Все эти варианты - отстой с точки зрения базы данных.

12
ответ дан 29 November 2019 в 02:46
поделиться

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

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

1
ответ дан 29 November 2019 в 02:46
поделиться

У вас уже есть правильный ответ, поэтому это замечание является дополнительным.

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

В ваших примерах вы использовали числа рядом с описанием каждого статуса. Если эти числа являются числовыми кодами, как я думаю, они должны быть, тогда вам не нужно значение 4, означающее «ожидание подтверждения клиента», в том же столбце, что и значение 4, означающее «Отменено». Если вы сделаете это, то вы не сможете использовать этот столбец в качестве ПК для вашей единственной истинной таблицы поиска.

Если вы дадите своей единственной истинной таблице поиска другой столбец, назовите ее «CodeType» и используйте «CodeType» и «Code» в качестве составного PK, то вы усложните больше, чем вносите, имея отдельную таблицу поиска для каждого кода. тип.

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

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

8
ответ дан 29 November 2019 в 02:46
поделиться

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

Изменить

Теперь вы добавили причины Анит и причины вашего отказа. Опять же, Анит имеет в виду наличие одной центральной таблицы для всех значений поиска в вашей базе данных. Итак, давайте посмотрим на номер 2:

«Вы вынуждены представлять каждый тип данных как строку с этим типом общей таблицы поиска».

Если я хочу {{ 1}} представляют другой тип данных, я могу добавить столбец для него в свою таблицу поиска.

Но с одной центральной таблицей для всех поисков теперь вы добавляете столбец, который должен заполняться только для одной конкретной операции поиска. Но собираетесь ли вы добавить ограничения CHECK, обеспечивающие это (фактически создавая NULL, но НЕ NULL, если ограничение Category = 'X' для столбца). Это может превратиться в кошмар обслуживания.

1
ответ дан 29 November 2019 в 02:46
поделиться

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

Кроме того, вы нарушили целостность данных из-за отношений PK / FK. Если у вас есть отдельные таблицы, FK означает, что вы не можете вводить значения, не входящие в справочную таблицу. Если вы используете одну большую таблицу, вы можете вводить значения, не соответствующие ситуации. Я помню одну базу данных, в которой я работал, где значение person_type было «Да» для некоторых записей.

4
ответ дан 29 November 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: