Подтвердить что ты не робот

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

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

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

Вкратце:

  • Таблицы поиска: хорошо.
  • Таблицы Common-lookup: bad.

Я буду держать мой вопрос ниже для справки.


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

  • "Вы теряете средства для обеспечения точного данные; ограничения. Объединив разные объекты в единый таблицы, у вас нет декларативных средств для ограничения значений определенного категория."
    Как сдерживающие значения теряют точность?

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

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

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

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

Мои примеры:

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

  • Забронировано
  • Назначено технику
  • Проблема диагностики
  • Ожидание подтверждения клиента
  • Отремонтировано и готово к отправке.
  • Отремонтировано и курьерское
  • Неправильно и готово к отправке.
  • Отклонено предложение

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

Другим распространенным примером может быть таблица OrderStatus, чтобы ограничить статус заказа:

  • В ожидании
  • Завершена
  • Высылаем
  • Отменено
  • Возвращено

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

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


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

-

4b9b3361

Ответ 1

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

Это происходит потому, что:

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

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

изменить

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

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

Все эти параметры сосать, с точки зрения базы данных.

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

Изменить

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

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

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

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

Ответ 5

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

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