Насколько важны таблицы поиска?

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

получить все сообщения, которые все еще открыты

"SELECT * FROM posts WHERE status_id = (SELECT id FROM statuses WHERE name = 'open')" 

Часто сами таблицы поиска очень короткие. Например, может быть только 3 или около того разных статусов. В этом случае было бы нормально искать определенный тип, используя константу или так в приложении? Что-то вроде

получить все сообщения, которые все еще открыты

 "SELECT * FROM posts WHERE status_id = ".Status::OPEN 

Или, что, если вместо использования чужого идентификатора я задал его как перечисление и запросил это?

Благодарю.

Ответ немного зависит, если вы ограничены небольшими системами регистрации в MyNonSQL или если вы думаете о SQL и больших базах данных.

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

Несмотря на то, что люди, которые пытаются изменить определение «нормализации» и т. Д. В соответствии с этой целью, нормализация не изменилась.

  • если в таблицах данных повторяются «Открытые» и «Закрытые», это простая ошибка нормализации. Если вы измените эти значения, вам может потребоваться обновить миллионы строк, что очень ограниченно. Такие значения обычно нормализуются в таблицу Reference или Lookup. Это также экономит место. Значение «Открыть», «Закрыто» и т. Д. Больше не дублируется.

  • второй момент – легкость изменения, если «Закрыто» было изменено на «Истек», снова необходимо изменить одну строку и это отразится на всей базе данных; тогда как в ненормализованных файлах необходимо изменить миллионы строк.

  • Добавление новых значений – это просто вопрос вставки одной строки.

  • в терминах Open Architecture таблица Lookup является обычной таблицей. Он существует в каталоге (стандартный SQL); любой инструмент отчета может найти его, если определено отношение PK :: FK, инструмент отчета также может найти это.

  • Enum предназначен только для не-SQLS. В SQL Enum является таблицей Lookup.

  • Следующий момент касается значимости ключа. Если Ключ не имеет смысла для пользователя, в порядке, используйте INT или TINYINT или что-то подходящее; число их постепенно; разрешить «пробелы». Но если ключ имеет смысл для пользователя, не используйте бессмысленное число, используйте значащий ключ. «M» и «F» для мужчин и женщин и т. Д.

    • Теперь некоторые люди будут входить в касательные к постоянству ПК. Это отдельная точка. Да, конечно, всегда используйте стабильное значение для ПК. «M» и «F» вряд ли изменится; если вы использовали {0,1,2,4,5,6}, ну не меняйте его, зачем вам это нужно. Эти ценности должны были быть бессмысленными, нужно было изменить только значимый ключ.
      ,
  • если вы используете значимые ключи, используйте короткие буквенные коды, которые могут быть поняты как пользователям, так и разработчикам (и вывести их из описания).

  • Поскольку ПК стабильны, особенно в таблицах Lookup, вы можете безопасно кодировать:

    WHERE status_id = 'O'

    Вам не обязательно вступать в таблицу Lookup и проверять значение «Открыть». Это теряет значение таблицы Lookup в сегментах кода.

SQL – это громоздкий язык, особенно когда речь идет о объединениях. Но это все, что у нас есть, поэтому нам нужно просто принять обременение и разобраться с ним. Ваш примерный код в порядке. Но более простые формы могут делать то же самое. Инструмент отчета будет генерировать:

  SELECT p. *,
          s.name
     FROM posts p, 
          статус s
     WHERE p.status_id = s.status_id 
     И p.status_id = 'O' 

  • Для банковских систем, где мы используем короткие коды, которые имеют смысл (поскольку они имеют смысл, мы не меняем их с помощью сезонов, мы просто добавляем к ним), учитывая таблицу Lookup, такую ​​как (тщательно подобранная, как и ISO Country Codes) :

     Eq Equity
     EqCS Equity / Common Share
     O Over The Counter
     OTC / Будущее 

    Код такой, как это распространено:

    WHERE InstrumentTypeCode LIKE "Eq%"

И пользователи будут выбирать значение из раскрывающегося списка, которое отображает «Открыть», «Закрыто» и т. Д., А не {0,1,2,4,5,6}, а не {M, F, U}. И в приложениях, и в инструменте отчетов. Без таблицы поиска вы не сможете этого сделать.

Наконец, если база данных была большой и поддерживала функции BI или DSS или OLAP (в большинстве нормализованных баз данных), то таблица Lookup фактически представляет собой измерение или вектор в анализе измерений. Если его там не было, тогда его нужно будет добавить, чтобы удовлетворить требования этого программного обеспечения, до того, как такие анализы могут быть установлены.

Для справочных таблиц я использую разумный первичный ключ – обычно это просто CHAR (1), который имеет смысл в домене с дополнительным полем Title (VARCHAR). Это может поддерживать принудительное соблюдение отношений, в то время как «поддержание простого SQL». Ключ, который нужно запомнить здесь, – это таблица поиска не содержит данные . Он содержит тождества . Некоторые другие идентификаторы могут быть названиями часовых поясов или присвоены кодам стран МОК .

Например, пол:

 Идентификатор метки
 Мужчины
 F Женский
 N Нейтральный
 select * from people where gender = 'M' 

В качестве альтернативы, ORM можно использовать, и ручное генерирование SQL, возможно, никогда не должно быть выполнено – в этом случае стандартный подход «суррогатный ключ» «int» прекрасен, потому что с ним что-то имеет дело 🙂

Счастливое кодирование.

Создайте функцию для каждого поиска. Нет простого способа. Вы хотите простоту производительности и запросов. Убедитесь, что поддерживается следующее. Вы могли бы создать SP_TestAppEnums для сравнения существующих значений поиска с функцией и поиска несинхронизированного / нулевого значения.

  CREATE FUNCTION [Enum_Post] (@ postname varchar (10))
 RETURNS int
 В ВИДЕ
 НАЧАТЬ
 DECLARE @postId int
 SET @postId =
 CASE @postname
 WHEN 'Open' THEN 1
 КОГДА «Закрыто» THEN 2
 КОНЕЦ

 RETURN @postId
 КОНЕЦ
 ИДТИ

 / * Вызов функции * /
 SELECT dbo.Enum_Post ('Открыть')
 SELECT dbo.Enum_Post ('Закрыто')

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

  • довольно статичный в природе – домен может расширяться, но он, вероятно, не будет сокращен.
  • их первичные ключевые значения также вряд ли будут меняться (например, status_id для статуса «open» вряд ли вдруг изменится на нечто иное, чем то, что было создано как).

Если приведенные выше предположения верны, нет никакой реальной необходимости добавлять все эти дополнительные таблицы в свои соединения, так что в вашем аргументе where вы можете использовать имя друга вместо значения id. Просто фильтруйте status_id прямо там, где вам нужно. Я подозреваю, что неключевой атрибут в предложении where («имя» в приведенном выше примере) скорее всего получит изменения, чем ключевой атрибут («имя» в приведенном выше примере): вы более защищены, ссылаясь на значение (ы) ключа ожидания таблицы домена в вашем соединении.

Доменные таблицы служат

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

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

YMMV: многое зависит от контекста и характера проблемного пространства.

Где это возможно (и это не всегда …), я использую это эмпирическое правило: если мне нужно жестко закодировать значение в моем приложении (а также оставить его в базе данных), а также сохранить это vlue в моей базе данных, тогда что-то не так с моим дизайном. Это НЕ ВСЕГДА истинно, но в основном, независимо от того, что имеет значение, оно либо представляет собой часть DATA, либо фрагмент PROGRAM LOGIC. Это редкий случай, что это и то, и другое.

НЕ, что вы не обнаружите, что обнаруживаете, какой из них находится на полпути в проекте. Но, как говорили другие, в любом случае могут быть компромиссы. Точно так же, как мы не всегда добиваемся «идеальной» нормализации в дизайне базы данных (по причине производительности или просто потому, что вы МОЖЕТЕ зайти слишком далеко в стремлении к безупречному совершенству …), мы можем сделать некоторые убедительные выборы о том, где мы найдите наши «поисковые» значения.

Лично, однако, я стараюсь стоять на своем правиле выше. Это либо DATA, либо PROGRAM LOGIC, либо редко. Если он заканчивается как (или IN) запись в базе данных, я стараюсь не допускать ее из кода приложения (за исключением, конечно, извлечения из базы данных …). Если он жестко закодирован в моем приложении, я стараюсь не использовать его в своей базе данных.

В тех случаях, когда я не могу соблюдать это правило, я ДОКУМЕНТ КОДА с моими рассуждениями, поэтому через три года какая-то бедная душа сможет выяснить, как она сломалась, если это произойдет.

Обозреватели убедили меня в ошибке моих путей. Однако этот ответ и дискуссия, которые шли вместе с ним, остались здесь для справки.

Я думаю, что константа здесь подходит, а таблица базы данных – нет. Когда вы разрабатываете свое приложение, вы ожидаете, что таблица статусов никогда не изменится, поскольку ваше приложение имеет жестко закодированное в нем, что означают эти статусы. Точка базы данных заключается в том, что данные внутри нее будут изменены. Бывают случаи, когда линии нечеткие (например, «эти данные могут меняться каждые несколько месяцев или около того …»), но это не один из нечетких случаев.

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

Ответ – «что имеет смысл».

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