JPA enum ORDINAL vs STRING

il est possible de définir les énumérations dans JPA en utilisant l'un ou l'autre

@Enumerated(EnumType.ORDINAL)

ou

@Enumerated(EnumType.STRING)

je me demande quels sont les avantages et les inconvénients de ces deux définitions?

J'ai entendu que ORDINAL performait mieux (est plus rapide) que STRING avec EclipseLink.

Est-ce vrai?

34
demandé sur jFrenetic 2011-07-22 15:32:06

6 réponses

je vais toujours STRING.

la Vitesse est rarement la question la plus importante - la lisibilité et la maintenabilité sont plus important.

j'utilise STRING parce qu'il est beaucoup plus facile d'inspecter manuellement les lignes de la base de données, mais plus important encore, je peux faire deux choses, sans toucher à la base de données, le ORDINAL ne peut pas gérer:

  1. je peux changer le de mon enum
  2. j' insert nouveaux énums dans le milieu de l'énumération de la liste

ces deux changements modifieront les valeurs ordinales des enums déjà utilisés dans la base de données, cassant ainsi les données existantes si vous utilisez ORDINAL.

si vous changez une valeur enum (pas si commune), la manipulation est simple:

UPDATE table SET enum_column = 'NEW_ENUM_NAME' where enum_column = 'OLD_ENUM_NAME';
58
répondu Bohemian 2012-04-07 19:53:00

Il est probable que ORDINAL est plus efficace, mais c'est mineur. Il y a quelques inconvénients à ORDINAL:

  • c'est moins lisible dans la base de données
  • si vous réorganisez vos définitions d'enum, la base de données ne sera pas cohérente.

STRING vous ne pouvez pas renommer vos énumérations.

choisissez l'un d'entre eux et utilisez - le tout au long de l'application-soyez cohérent.

Si votre base de données va être utilisé par d'autres clients/langues - utiliser STRING, c'est plus lisible.

14
répondu Bozho 2011-07-22 14:03:26

je préfère l'utilisation de Ordinal mais ce vraiment dépend de l'utilisation.

Par exemple:

Vous avez un enum, pour enregistrer tous vos états utilisateurs, dans ce cas, l'ordre n'a pas d'importance, et vous pouvez ajouter d'autres états dans le futur (la Meilleure utilisation est @Enumerated(EnumType.ORDINAL)):

public enum UserStates { ACTIVE, DELETED, PENDING }

mais maintenant, vous avez un enum, pour sauver les Plantes dans le système solaire (meilleur usage @Enumerated(EnumType.STRING)):

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

maintenant, pensez que vous voulez réorganiser vos planètes, avec @Enumerated(EnumType.ORDINAL) vous ne pouvez pas, parce que votre base de données ne peut pas connaître le nouvel ordre dans votre fichier Java.

vous pouvez réordonner vos Plantes en utilisant @Enumerated(EnumType.STRING) parce que votre planète est liée au nom enum, pas à l'ordre enum.

de toute façon, vous pouvez modifier votre @Enumerated(EnumType.STRING)les énumérations, parce qu'ils sont liés à l'ordre, mais vous ne pouvez pas changer votre @Enumerated(EnumType.STRING)énums parce qu'ils utiliseront comme nouveaux énums.

les types de chaînes de caractères sont plus lisibles dans la base de données, mais occuperont plus de taille qu'un les données ordinales. Peut-être sont utiles si la base de données est utilisée par Plus de clients, mais il est préférable d'avoir une bonne documentation du logiciel que d'économiser 1000 fois "terre" que "4"

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

Planets
------------
ID | Name |
------------
1 | EARTH
2 | EARTH
3 | MARS
4 | EARTH
2
répondu Genaut 2017-07-21 18:20:51

C'est une bonne question. Dans le passé J'ai utilisé la corde mais aujourd'hui ma préférence est Ordinal.

le principal inconvénient de la chaîne est pour les AD. Oui, les Administrateurs de bases de données. Avec la corde ils aucune idée quelles sont les valeurs possibles de la colonne. Cette information se trouve dans le code de demande. Le DBA seulement peut avoir une idée sur les valeurs possibles groupant l'information existante sur la table, mais il ne sera jamais sûr des autres valeurs possibles ou si Nouveau les valeurs sont ajoutées, jusqu'à ce que l'application les insère sur le tableau.

Dans l'Ordinal vous avez le même problème. Mais ma préférence pour Ordinal est venu à une solution au problème DBA qui semble naturel à la base de données. Vous créez une nouvelle table pour afficher les valeurs possibles de L'énumérateur sur la base de données, avec une clé étrangère entre la colonne (Valeur énum ordinale) et cette nouvelle table. Cette stratégie est décrite et mise en œuvre ici.

Sur le problème que quelqu'un pourrait réorganiser le recenseur et briser le système, un simple test de l'unité peut traiter ce problème et garantir que personne ne les réorganisera sans un bon avertissement. La même idée est valable sur le renommage de l'agent Recenseur. Ainsi, renommer (sur la chaîne) ou réorganiser (sur Ordinal) accidentellement n'est pas vraiment un argument fort contre la chaîne ou l'approche ordinale.

soit dit en passant, les développeurs ont plus besoin de renommer que de réordonner un recenseur, donc c'est un point positif de plus dans l'utilisation Ordinal.

ainsi, avec cette approche, vous résolvez le problème principal de L'Ordinal (maintenant, est lisible), l'information occupera moins d'espace sur la base de données et votre DBA sera heureux.

2
répondu Dherik 2018-02-06 18:52:31

cela dépend de votre application, s'il y a plus de chances que vous ajoutiez plus d'enums utilisez le type String, s'il y a plus de chances que vous changiez le nom de vos enums utilisez Ordinal.

0
répondu samid hamza 2017-04-08 15:12:04

Êtes-vous vraiment sûr qu'une base de données lisible par un humain est ce dont vous avez besoin? Stocker la valeur de la chaîne est un gaspillage d'espace. Le seul compromis avec la lisibilité pourrait être d'utiliser @Enumered (STRING) et la colonne de base de données de carte comme ENUM (si vous utilisez mysql... Je suppose que d'autres SGBD ont quelque chose de similaire) mais c'est une vraie douleur quand vous devez changer les noms d'enum.

-4
répondu Lothruin 2012-01-27 12:04:05