Enum storage в поле Database - PullRequest
       49

Enum storage в поле Database

3 голосов
/ 19 июня 2009

Лучше ли хранить перечисление значение или перечисление имя в поле таблицы базы данных?

Например, я должен хранить 'TJLeft' как строку или ее эквивалентное значение в базе данных?

Public Enum TextJustification
  TJLeft
  TJCenter
  TJRight
End Enum

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

Редактировать -

Некоторые перечисления находятся под моим контролем, но некоторые от третьих лиц.

Ответы [ 8 ]

5 голосов
/ 19 июня 2009

Другая причина для сохранения числового значения заключается в том, что вы используете атрибут [Flags] в своем перечислении в тех случаях, когда вы можете разрешить использование нескольких значений перечисления. Например, вы хотите, чтобы кто-то выбирал, в какие дни недели они доступны для чего-либо ...

[Flags] 
public enum WeekDays     
{
   Monday=1,
   Tuesday=2,
   Wednesday=4,
   Thursday=8,
   Friday=16
}

В этом случае вы можете сохранить числовое значение в БД для любой комбинации значений (например, 3 == Понедельник и Вторник)

2 голосов
/ 05 января 2010

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

Вот несколько причин, по которым числовые значения лучше строковых идентификаторов:

  • Это самый простой способ представить значение
  • Поиск / сортировка в базе данных быстрее
  • Более низкая стоимость хранения базы данных (что может быть серьезной проблемой для некоторых приложений)
  • Вы можете добавить [Flags] к своему enum и не нарушать свой код и / или существующие данные
  • Для [Flags] хранится в строковом поле:
    • Плохо нормализованные данные
    • Может генерировать ложноположительные аномалии при сопоставлении (т. Е. Если у вас есть члены "Sales" и "RetailSales", простой поиск по подстроке "Sales" будет совпадать для любого типа). Это должно быть ограничено либо с помощью регулярного выражения на границах слов (привередливы в использовании баз данных и медленно), либо с помощью ограничения в самом перечислении, которое нестандартно, подвержено ошибкам и очень трудно отлаживается.
  • Для строковых полей (либо [Flags], либо нет), если база данных запутана, это поле необходимо обработать, что сильно влияет на возможности и эффективность при выполнении поиска / сортировки кода, как упоминалось в предыдущем пункте
  • Вы можете переименовать любого участника, не нарушая код базы данных и / или существующие данные клиента.
  • Меньше пространства / времени для передачи данных по проводной связи

Есть только две ситуации, когда использование имен членов в базе данных может быть преимуществом:

  • Если вы делаете много редактирования данных вручную ... но кто это делает? И если да, есть большая вероятность, что вы все равно не будете использовать enum.
  • Сторонние перечисления, где они могут быть не такими прилежными, чтобы поддерживать числовые константы значений. Но я должен сказать, что любой, кто выпускает прилично написанный API, в подавляющем большинстве случаев будет достаточно умен, чтобы поддерживать значения enum постоянными. (Идентификаторы должны оставаться неизменными, поскольку их изменение нарушит существующий код.)

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

  • Добавление функциональности [Flags] требует использования соединительной таблицы, что означает более сложные запросы (существующие необходимо переписать) и дополнительную сложность. А как насчет существующих данных клиента?
  • Если идентификатор хранится в таблице данных, какой смысл иметь таблицу поиска в первую очередь?
  • Если числовое значение хранится в таблице данных, вы ничего не получите, так как вам все равно придется искать идентификатор из таблицы поиска. Чтобы сделать это проще, вы можете создать представление ... для каждой таблицы, в которой есть значение enum. И тогда давайте даже не будем думать о [Flags] перечислениях.
  • Введение любого вида синхронизации между базой данных и кодом просто вызывает проблемы. А как насчет существующих данных клиента?
1 голос
/ 19 июня 2009

Я всегда использую справочные таблицы, состоящие из полей

  • OID int (pk) в качестве числового значения
  • ProgID varchar (уникальный) в качестве идентификатора значения в C # (т. Е. Константное имя или символ перечисления)
  • ID nvarchar в качестве отображаемого значения (UI)

dbscript позволяет мне генерировать код C # из моих справочных таблиц, поэтому мой код всегда синхронизирован с базой данных.

0 голосов
/ 09 июля 2011

если вы пытаетесь вернуть значения enum, хранящиеся в базе данных, попробуйте это

EnumValue = DirectCast([Enum].Parse(GetType(TextJustification), reader.Item("put_field_name_here").ToString), TextJustification)

скажите, работает ли он у вас

0 голосов
/ 19 июня 2009

Как часто это зависит от многих вещей:

Вы хотите отсортировать по естественному порядку перечислений? Используйте числовые значения. Вы работаете непосредственно в базе данных, используя инструмент низкого уровня? используйте имя. У вас есть огромные объемы данных, а производительность - это проблема? используйте номер

Для меня самая важная проблема - это ремонтопригодность:

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

0 голосов
/ 19 июня 2009

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

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

0 голосов
/ 19 июня 2009

Лучше использовать целочисленное представление ... Если вам нужно изменить Enum позже (добавить дополнительные значения и т. Д.), Вы можете явно присвоить целочисленное значение значению Enum, чтобы ваше представление Enum в коде все равно совпадало с тем, что вы есть в базе данных.

0 голосов
/ 19 июня 2009

Сохранить идентификатор (значение) и имя varchar; это позволяет вам запросить в любом случае. Поиск по имени целесообразен, если ваши идентификаторы (значения) могут быть не синхронизированы позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...