Какие хорошие стратегии для работы с магическими числами в вашей базе данных? - PullRequest
4 голосов
/ 06 марта 2009

Я работаю с самыми разными процессами, которые имеют предложения WHERE, которые выглядят так:

WHERE ... AND ( ( myTbl.myValue = 1234) 
    or (myTbl.myValue = 1235) )-- Value =  No

Я обсуждал это с некоторыми коллегами, и такой код кажется неизбежным. Я думаю, что это хорошая идея - поместить этот код в одно (и только одно) место. Это может быть представление, это может быть таблица и т. Д. Я думаю, что представление, которое выбирается из базовой таблицы и имеет битовое поле, которое говорит, что значение 1234 или 1235 равно 0. Или 'N' и т. Д. Таким образом, я могу добавлять значения «Нет» по желанию без необходимости изменения кода. Я бы не использовал UDF для этого, слишком много вызовов функций, если вы используете его в соединении.

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

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

PS: я видел несколько вопросов о магических числах, но ничего специфического для базы данных.

Ответы [ 8 ]

3 голосов
/ 06 марта 2009

Сколько магических чисел мы говорим? Если это меньше, чем несколько тысяч, положите их в таблицу и сделайте соединение. Если они часто используются в предложениях WHERE как согласованная группа (например, 1234 и 1235 в вашем примере), присвойте столбец категории и используйте IN или EXISTS. (Ни один из них не будет значимым ударом по производительности с небольшим количеством магических чисел и соответствующим индексом.)

Я терпеть не могу жестко запрограммированные числовые значения, подобные приведенным в вашем примере, для всего, кроме специальных операторов SQL. Это делает обслуживание настоящим PITA позже.

3 голосов
/ 06 марта 2009

В Oracle вы можете настроить детерминированные функции такого рода функции, которые обращают внимание на СУБД, которую нужно вызывать только один раз.

create or replace package MAGIC is
  function magic_number return  number DETERMINISTIC;
end;
/

create or replace package body MAGIC is
  function magic_number return  number DETERMINISTIC
  is
  begin
    return 123;
  end;
end;
/

SELECT MAGIC_DATE
  FROM MAGIC_TABLE
 WHERE MAGIC_ID = magic.magic_number;
1 голос
/ 06 марта 2009

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

1 голос
/ 06 марта 2009

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

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

1 голос
/ 06 марта 2009

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

Однако я обнаружил, что наилучшим решением является сохранение поиска (функция / перечисление и т. Д.) В программном коде (или SP, если вы это используете). Убедитесь, что вы всегда используете этот поиск для добавления или выбора данных из БД.

0 голосов
/ 06 марта 2009

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

0 голосов
/ 06 марта 2009

Используя SqlServer и, возможно, другие диалекты, вы можете создавать функции, которые возвращают магическое число, поэтому ваш sql станет

WHERE ... AND ( ( myTbl.myValue = MagicFunction1())     or (myTbl.myValue = MagicFunction2()) )-- Value =  No

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

WHERE ... AND ( ( myTbl.myValue = ProductFunction(1))     or (myTbl.myValue = ProductFunction(2)) )-- Value =  No
0 голосов
/ 06 марта 2009

Поскольку мы выполняем запросы в виде строк, это обычно что-то вроде

"AND myTbl.iTpe = "+AnEnum.THE_TYPE.ordinal()+"..."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...