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

JPA Enum ORDINAL vs STRING

Можно определить перечисления в JPA, используя либо

@Enumerated(EnumType.ORDINAL)

или

@Enumerated(EnumType.STRING)

Интересно, какие преимущества и недостатки этих двух определений?

Я слышал, что ORDINAL работает лучше (быстрее), чем STRING с EclipseLink.
Это правда?

4b9b3361

Ответ 1

Я всегда иду STRING.

Скорость редко является самой важной проблемой - более важны читаемость и ремонтопригодность.

Я использую STRING, потому что гораздо проще вручную проверять строки из базы данных, но что более важно, я могу сделать две вещи, не касаясь базы данных, ORDINAL не может обрабатывать:

  • Я могу изменить порядок моих перечислений
  • Я могу вставить новые перечисления в середине списка перечислений

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

Если вы измените значение перечисления (не так часто), обработка его проста:

UPDATE table SET enum_column = 'NEW_ENUM_NAME' where enum_column = 'OLD_ENUM_NAME';

Ответ 2

Вероятно, что ORDINAL более эффективен, но этот незначительный. Есть несколько минусов для ORDINAL:

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

С помощью STRING вы не можете переименовать свои перечисления.

Выберите один из них и используйте его во всем приложении - будьте последовательны.

Если ваша база данных будет использоваться другими клиентами/языками - используйте STRING, это более читаемо.

Ответ 3

Я предпочитаю использовать Ordinal, но это действительно зависит от использования.

Пример:

У вас есть перечисление, чтобы сохранить все ваши пользовательские состояния, в этом случае порядок не имеет значения, и вы можете добавить больше состояний в будущем (наилучшее использование @Enumerated(EnumType.ORDINAL)):

public enum UserStates { ACTIVE, DELETED, PENDING }

Но теперь у вас есть перечисление, чтобы сохранить растения в Солнечной системе (Лучшее использование @Enumerated(EnumType.STRING)):

public enum Planets {MERCURY,VENUS,EARTH,MARS,JUPITER,SATURN,URANUS,NEPTUNE,PLUTO,NINE}

Теперь подумайте, что вы хотите изменить порядок своих планет, а @Enumerated(EnumType.ORDINAL) вы не можете, потому что ваша база данных не может знать новый порядок в вашем файле Java.

Вы можете изменить порядок своих растений с помощью @Enumerated(EnumType.STRING), потому что ваша Планета связана с именем перечисления, а не с порядком перечисления.

В любом случае вы можете изменить свои перечисления @Enumerated(EnumType.STRING), потому что они связаны с порядком, но вы не можете изменить свои перечисления @Enumerated(EnumType.STRING), потому что они будут использовать как новые перечисления.

Типы строк более читабельны в базе данных, но будут иметь больший размер, чем порядковые данные. Возможно, полезно, если база данных используется больше клиентов, но лучше иметь хорошую документацию по программному обеспечению, чем экономить 1000 раз "ЗЕМЛЯ", чем "4"

USERSTATE
------------
ID | STATE |
------------
1 | 1
2 | 2
3 | 1

Planets
------------
ID | Name |
------------
1 | EARTH
2 | EARTH
3 | MARS
4 | EARTH

Ответ 4

Это хороший вопрос. В прошлом я использовал String, но сегодня я предпочитаю обычно Ordinal.

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

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

Что касается проблемы, связанной с тем, что кто-то может переупорядочить Enumerator и сломать систему, простой unit тест может решить эту проблему и гарантировать, что никто не изменит их порядок без предупреждения. Эта же идея действительна при переименовании Enumerator. Таким образом, переименование (в String) или изменение порядка (в Ordinal) случайно не является сильным аргументом против подхода String или Ordinal.

Кстати, разработчикам больше нужно переименовывать, чем переупорядочивать Enumerator, так что это еще один положительный момент использования Ordinal.

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

Ответ 5

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

Ответ 6

Здесь много полезных советов, но я просто хотел добавить кое-что, чего еще не видел:

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

Ответ 7

Я бы предпочел EnumType.STRING. Недостатком EnumType.ORDINAL является влияние времени и желание сохранять перечисления в логическом порядке. С EnumType.ORDINAL любые новые элементы enum должны быть добавлены в конец списка, иначе вы случайно измените значение всех ваших записей. пожалуйста, проверьте эту ссылку: https://tomee.apache.org/examples-trunk/jpa-enumerated/

Ответ 8

Вы действительно уверены, что читаемая пользователем база данных - это то, что вам нужно? Хранение строкового значения - пустая трата пространства. Единственным компромиссом с читабельностью может быть использование @Enumerated (STRING) и столбца базы данных карты как ENUM (если вы используете mysql... Я предполагаю, что другие dbms имеют что-то подобное), но это настоящая боль, когда вам нужно изменить имена переименований.