Хранение перечислимых значений в базе данных - PullRequest
20 голосов
/ 25 мая 2011

К вашему сведению: я имею в виду SQL Server 2000-8 и C #.Таким образом, СУБД с поддержкой enum, например MySql, не является темой моего вопроса.

Я знаю, что этот вопрос задавался несколько раз в SO.Но, тем не менее, я вижу в ответах, что для хранения значений enum используются разные подходы.

  1. Сохранить перечисление как int в db и извлечь значение перечисления (или атрибут описания перечисления, используя отражение) в коде :
    thisэто подход, который я обычно использую.Проблема в том, что когда я пытаюсь выполнить запрос из базы данных в SSMS, извлеченные данные трудно понять.

  2. Сохранить перечисление как строку (varchar) в БД и преобразоватьобратно к int в коде.
    На самом деле, это может быть лучшим решением.Но (не смейтесь!) Это не так.Я не уверен в минусах.(За исключением большего количества места в дБ, которое обычно приемлемо). Так что еще против этого подхода?

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

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

Ответы [ 2 ]

18 голосов
/ 25 мая 2011

Нет определенного правила проектирования (о котором я знаю), но я предпочитаю подход № 1.

  1. Подход, который я предпочитаю. Это просто, и перечисления обычно достаточно компактны, поэтому я начинаю вспоминать, что означают цифры.
  2. Это более читабельно, но может помешать рефакторингу или переименованию ваших значений перечисления, когда вы захотите. Вы теряете некоторую свободу своего кода. Внезапно вам нужно подключить администратора баз данных (в зависимости от того, где / как вы работаете) просто для того, чтобы изменить значение перечисления или страдать от него. Анализ enum также оказывает некоторое влияние на производительность, поскольку такие вещи, как Locale, вступают в игру, но, вероятно, незначительны.
  3. Какую проблему это решает? У вас все еще есть нечитаемые числа в таблице где-то, если только вы не хотите добавить издержки объединения. Но иногда это тоже правильный ответ в зависимости от того, как используются данные.

EDIT : У Криса в комментариях было хорошее замечание: если вы все-таки выберете числовой подход, вам следует явно назначить значения, чтобы вы могли также изменить их порядок. Например:

public enum Foo
{
     Bar = 1,
     Baz = 2,
     Cat = 9,
     //Etc...
}
6 голосов
/ 25 мая 2011

Одна идея, которую я видел раньше, это ваш вариант 3 более или менее

  • Таблица в базе данных (для внешних ключей и т. Д.)
  • Соответствующий Enum в клиентекод
  • Проверка запуска (через вызов базы данных), чтобы убедиться, что они совпадают

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

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

...