2008-12-12 5 views
45

Mon exigencede type MySQL ENUM vs tables de jointure

Une table a besoin de maintenir une colonne d'état.

Cette colonne représente l'un des 5 états.


conception initiale

je me suis dit que je peux faire une colonne entière et représentent les états en utilisant une valeur numérique.

  • 0 = début
  • 1 = en cours d'exécution
  • 2 =
  • se sont écrasés
  • 3 = mis en pause
  • 4 = arrêté

Depuis que je ne veux pas que mon application pour maintenir la mappage des entiers à leur description de chaîne, j'ai l'intention de placer ceux-ci dans une table de description d'état séparée (en s'appuyant sur une relation FK).

Ensuite, j'ai découvert que MySQL a un type ENUM qui correspond exactement à mes besoins. Outre une dépendance directe à MySQL, y a-t-il des pièges à l'utilisation du type ENUM?

+0

Le type de données ENUM commence à compter avec 1, pas avec 0 comme indiqué. – Tomalak

+1

voir: http://dev.mysql.com/doc/refman/5.0/en/enum.html – Tomalak

Répondre

81
  • Changer l'ensemble des valeurs dans un ENUM nécessite une ALTER TABLE ce qui pourrait provoquer une restructuration de table - une opération très coûteuse (la restructuration de la table ne se produit pas si vous ajoutez simplement une nouvelle valeur à la fin de la ENUM définition, mais si vous en supprimez un, ou changez l'ordre, il fait une restructuration de table). Alors que la modification de l'ensemble des valeurs dans une table de recherche est aussi simple que INSERT ou DELETE.

  • Il est impossible d'associer d'autres attributs aux valeurs d'un ENUM, telles que celles qui sont supprimées et celles qui peuvent être placées dans une liste déroulante dans votre interface utilisateur. Toutefois, une table de recherche peut inclure des colonnes supplémentaires pour ces attributs.

  • Il est très difficile d'interroger un ENUM pour obtenir une liste de valeurs distinctes, essentiellement vous oblige à interroger la définition du type de données à partir INFORMATION_SCHEMA et analyse la liste de blob retourné. Vous pouvez essayer SELECT DISTINCT status à partir de votre table, mais cela n'obtient que les valeurs d'état actuellement utilisées, qui peuvent ne pas être toutes les valeurs dans ENUM. Cependant, si vous gardez les valeurs dans une table de consultation, il est facile d'interroger, de trier, etc.

Je ne suis pas un grand fan de ENUM, comme vous pouvez le dire. :-)

La même chose s'applique aux contraintes CHECK qui comparent simplement une colonne à un ensemble fixe de valeurs. Bien que MySQL ne supporte pas les contraintes CHECK de toute façon.

+1

Merci Bill pour vos conseils. Parfois, des abstractions comme le type ENUM peuvent sembler simples et élégantes, mais c'est une bombe à retardement administrative. – ashitaka

+4

Oh j'en ai oublié un: ENUM n'est pas standard SQL et AFAIK aucune autre marque de base de données ne le supporte. Cela limite donc votre portabilité si vous l'utilisez. –

+3

Quelqu'un m'a donné un downvote. Quand vous donnez des réductions, pouvez-vous expliquer votre objection? Peut-être que je peux améliorer la réponse. –

0

Une table serait plus facile à internationaliser. Mais tout comme une classe en dehors de la base de données. Les énumérations me semblent être une solution à la recherche d'un problème - ou ce que vous utilisez quand vous ne savez que des bases de données.

9

Voici un article sur speed comparison of enum. Peut-être que cela donne quelques indices. À mon humble avis, il devrait être limité à une utilisation dans la liste fixe de chaînes ("Oui/Non", "Enfant/Adulte") qui, avec une probabilité de 99% ne change pas à l'avenir.

7

Les énumérations dans mysql sont mauvaises pour les raisons déjà expliquées.
Je peux ajouter le fait suivant: Enum n'assure aucune sorte de validation côté serveur. Si vous insérez une ligne avec une valeur qui ne se termine pas dans la définition enum, vous obtiendrez une valeur agréable ou NULL dans le DB, en fonction de la capacité NULL de la déclaration de champ enum.

Mon point sur les tinyints:
- énumérations sont limités à 65535
- si vous n'avez pas besoin de plus de 256 valeurs, tinyint prendra moins de place pour chaque ligne, et son comportement est beaucoup plus « prédictible » .

+0

Attendez, sont enums ou minuscules mauvais? Ou les deux? –

+1

Bien sûr, il voulait dire que «enums» sont mauvais pour les raisons expliquées. – abenson

+0

Abenson a raison, j'ai édité ma réponse. – MatthieuP

2

Si vous avez beaucoup de données dans votre base de données (plus de données alors vous avez de la RAM) et que les valeurs ENUM ne changeront JAMAIS, je choisirais ENUM plutôt que la jointure. Cela devrait être plus rapide. Pensez-y, dans le cas de jointure, vous avez besoin d'un index sur votre clé étrangère et d'un index sur votre clé primaire dans l'autre table. Comme l'a dit Riho, voir les repères.

Questions connexes