JPA Enum ORDINAL vs STRING


Es posible definir enumeraciones en JPA usando

@Enumerated(EnumType.ORDINAL)

O

@Enumerated(EnumType.STRING)

Me pregunto cuáles son las ventajas y desventajas de esas dos definiciones?

He oído que ORDINAL funciona mejor (es más rápido) que STRING con EclipseLink.
Es eso cierto?

Author: jFrenetic, 2011-07-22

6 answers

Siempre voy STRING.

La velocidad rara vez es el tema más importante - la legibilidad y la mantenibilidad son más importantes.

Uso STRING porque es mucho más fácil inspeccionar manualmente las filas de la base de datos, pero lo más importante, puedo hacer dos cosas, sin tocar la base de datos, el ORDINAL no puede manejar:

  1. Puedo cambiar el orden de mis enum
  2. I can insert new enums in the middle of the enum list{[17]]}

Ambos de estos cambios alterarán los valores ordinales de las enumeraciones ya en uso en la base de datos, rompiendo así los datos existentes si está utilizando ORDINAL.

Si cambia un valor de enumeración (no tan común), manejarlo es simple:

UPDATE table SET enum_column = 'NEW_ENUM_NAME' where enum_column = 'OLD_ENUM_NAME';
 58
Author: Bohemian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-07 19:53:00

Es probable que ORDINAL sea más eficiente, pero eso es menor. Hay algunas desventajas de ORDINAL:

  • es menos legible en la base de datos
  • si reordena sus definiciones de enumeración, la base de datos no será consistente.

Con STRING no puedes cambiar el nombre de tus enumeraciones.

Elija uno de ellos y úselo durante toda la aplicación - sea consistente.

Si su base de datos va a ser utilizada por otros clientes/lenguajes - use STRING, es más legible.

 14
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-22 14:03:26

Yo prefiero el uso de Ordinal pero esto realmente depende del uso.

Por ejemplo:

Tiene una enumeración, para guardar todos los estados de usuario, en este caso el orden no importa, y puede agregar más estados en el futuro (el mejor uso es @Enumerated(EnumType.ORDINAL)):

public enum UserStates { ACTIVE, DELETED, PENDING }

Pero ahora, tienes una enumeración, para salvar las Plantas en el Sistema Solar (Mejor uso @Enumerated(EnumType.STRING)):

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

Ahora piensa que quieres reordenar tus planetas, con @Enumerated(EnumType.ORDINAL) no puedes, porque tu base de datos no puede saber el nuevo orden en su archivo Java.

Puedes reordenar tus Plantas usando @Enumerated(EnumType.STRING) porque tu Planeta está vinculado al nombre enum, no al orden enum.

De todos modos, puede modificar sus @Enumerated(EnumType.STRING) enumeraciones porque están vinculadas al orden, pero no puede cambiar sus @Enumerated(EnumType.STRING) enumeraciones porque se usarán como nuevas enumeraciones.

Los tipos de cadena son más legibles en la Base de datos, pero ocuparán más tamaño que un dato ordinal. Tal vez sean útiles si la base de datos es utilizada por más clientes, pero es mejor tener una buena documentación del software que guardar 1000 veces "TIERRA" que "4"

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

Planets
------------
ID | Name |
------------
1 | EARTH
2 | EARTH
3 | MARS
4 | EARTH
 2
Author: Genaut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 18:20:51

Esta es una buena pregunta. En el pasado usé String pero hoy mi preferencia es Ordinal.

La principal desventaja de la cadena es para los DBA. Sí, los DBAS. Con la cadena no tienen idea cuáles son los posibles valores de la columna. Esta información está en el código de la aplicación. El DBA solo puede tener alguna idea sobre los valores posibles que agrupan la información existente en la tabla, pero nunca estará seguro sobre los otros valores posibles o si se agregan nuevos valores, hasta que la aplicación los inserte en la mesa.

En el Ordinal tienes el mismo problema. Pero mi preferencia por Ordinal llegó a una solución al problema de DBA que parece natural para la base de datos. Cree una nueva tabla para mostrar los posibles valores del Enumerador en la base de datos, con una clave foránea entre la columna (valor de enumeración ordinal) y esta nueva tabla. Esta estrategia se describe e implementa aquí.

Sobre el problema de que alguien podría reordenar el Enumerador y romper el sistema, una simple prueba unitaria puede hacer frente a este problema y garantizar que nadie los reordenará sin una buena advertencia. La misma idea es válida para cambiar el nombre del Enumerador. Por lo tanto, renombrar (en cadena) o reordenar (en Ordinal) accidentalmente no es realmente un argumento fuerte contra el enfoque de Cadena u Ordinal.

Por cierto, los desarrolladores tienen más necesidad de renombrar que reordenar un Enumerador, por lo que este es un punto positivo más en uso Ordinal.

Entonces, con esto enfoque, se resuelve el problema principal del Ordinal (ahora, es legible), la información ocupará menos espacio en la base de datos y su DBA será feliz.

 2
Author: Dherik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-06 18:52:31

Depende de su aplicación, si hay más posibilidades de que agregue más enums use el tipo de cadena, si hay más posibilidades de que cambie el nombre de sus enums use Ordinal.

 0
Author: samid hamza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-08 15:12:04

¿Está realmente seguro de que una base de datos legible por humanos es lo que necesita? Almacenar el valor de la cadena es una pérdida de espacio. El único compromiso con la legibilidad podría ser usar @Enumerated (STRING) y map database column como ENUM (si está utilizando mysql... Supongo que otros dbms tienen algo similar) pero es un verdadero dolor cuando tienes que cambiar los nombres de enumeración.

 -4
Author: Lothruin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-27 12:04:05