ENUM: maximale (sinnvolle) Größe?

16 views
Skip to first unread message

Karsten Wutzke

unread,
Apr 8, 2010, 7:40:57 AM4/8/10
to
Hallo,

gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
ENUM?

Gegeben z.B.:

CREATE TABLE Languages
(
iso_code ENUM('en', 'de', 'fr', ...) NOT NULL PRIMARY KEY
)

Die Liste wird eher selten geändert, aber wo ist der Punkt zu sagen,
dass man jetzt lieber eine extra Tabelle nimmt? Bei 7 Elementen? 10?
20? 34? 57? 101? 666?

Ich meine mich daran zu erinnern, dass irgendjemand mal gesagt hat,
dass ENUMs nur für eine eher geringe Anzahl von Elementen Sinn macht.
Allerdings verstehe ich nicht, was an längeren Listen falsch sein
sollte. Eine extra Tabelle spielt ja eigentlich nur eine Rolle, wenn
man den ENUM von mehr als einer Tabelle aus braucht und die Datensätze
wiederverwenden will. Wenn das im Design gerade keine Rolle spielt,
welchen Grund gibt es ENUM mit längeren Listen nicht zu verwenden?

Ein weiteres Beispiel wären hier Ländercodes:

http://www.iso.org/iso/iso-3166-1_decoding_table

Die Codes sind an sich ja CHAR(2) und es gibt 26*26 = 676 potentielle
Kombinationen, von denen jedoch nicht alle gültig sind. Ich könnte
also auf die Idee kommen einen riesigen ENUM zu erstellen
ENUM('AD', ..., 'ZW') mit mehreren hundert Ländercodes.

Macht sowas Sinn und wenn warum/warum nicht? Bei wie vielen Elementen
ist die Grenze und warum?

Meinungen dazu nehme ich gerne entgegen.

Karsten

Andreas Scherbaum

unread,
Apr 8, 2010, 3:30:41 PM4/8/10
to
Hallo,

Karsten Wutzke <kwu...@web.de> wrote:
>
> gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
> ENUM?
>

> [...]


>
> Die Liste wird eher selten geändert

Selten oder gar nicht?
ENUMs machen imho nur Sinn, wenn sich die Liste wirklich nicht mehr
verändert. Andernfalls muss man die Definition des ENUM anfassen - und
kann eigentlich gleich eine weitere Tabelle nehmen.


Deine Liste mit Ländercodes ist nun wirklich nicht statisch,
aufgrund von irgendwelchen Gründen kommen da welche hinzu oder
fallen weg. Nimm also besser eine Tabelle dafür ;-) Das
vereinfacht die Pflege.


Bis dann

--
Andreas 'ads' Scherbaum
Failure is not an option. It comes bundled with your Microsoft product.
(Ferenc Mantfeld)

Kristian Köhntopp

unread,
Apr 9, 2010, 8:54:57 AM4/9/10
to
On 2010-04-08 13:40:57 +0200, Karsten Wutzke said:
> gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
> ENUM?

ENUM hat in MySQL 5.1 einige Eigenschaften, die überraschend sind.

Zum Beispiel

root@localhost [kris]> create table t (id integer unsigned not null
primary key, e enum('a', 'b', 'c') not null ) engine = innodb;
Query OK, 0 rows affected (0.21 sec)


root@localhost [kris]> insert into t values (1, '');
Query OK, 1 row affected, 1 warning (0.00 sec)

Warning (Code 1265): Data truncated for column 'e' at row 1

root@localhost [kris]> insert into t values (2, 'c');
Query OK, 1 row affected (0.00 sec)

root@localhost [kris]> select id, e, hex(e), e+0 from t;
+----+---+--------+-----+
| id | e | hex(e) | e+0 |
+----+---+--------+-----+
| 1 | | | 0 |
| 2 | c | 63 | 3 |
+----+---+--------+-----+
2 rows in set (0.00 sec)

Obwohl t.e ein ENUM ist, das per Definition keinen Wert '' zuläßt, hat
MySQL den Wert '' abspeichern können, wenn auch mit einer Warnung.

Bei der Kontrollausgabe sieht man bei der Konvertierung nach INTEGER,
daß ein ENUM intern Zahl gespeichert wird, wobei dem ersten Wert die
Zahl 1, dem nächsten die Zahl 2 und so weiter zugeordnet wird. Der Wert
'', intern als 0 repräsentiert (und von NULL verschieden) wird immer
zugelassen.

Abhilfe schaffte hier strict mode, etwa

root@localhost [kris]> set sql_mode = STRICT_ALL_TABLES;
Query OK, 0 rows affected (0.00 sec)
root@localhost [kris]> insert into t values (3, '');
ERROR 1265 (01000): Data truncated for column 'e' at row 1

Die data truncation warning wird dann zum Error und läßt den INSERT
scheitern. Das bringt andere Probleme mit sich, aber das ist eine
andere Geschichte, die ein anderes Mal erzählt werden soll.


Das ENUM wird intern als TINYINT oder SHORTINT repräsentiert, belegt
also entweder einen oder zwei Bytes pro Wert und kann entsprechend
maximal 64k Werte annehmen.

> Ich meine mich daran zu erinnern, dass irgendjemand mal gesagt hat,
> dass ENUMs nur für eine eher geringe Anzahl von Elementen Sinn macht.

Das Problem lag in der Vergangenheit eher bei der Kombination von
Tabellengröße und Änderungshäufigkeit der Definition.

Eine Änderung der Wertemenge ist halt ein DDL-Statement, also ein ALTER
TABLE und MySQL mußte bisher für das Ändern der ENUM-Definition die
Tabelle umkopieren. Wird die Tabelle größer, kann das unangenehm lange
dauern, da die Tabelle während des Umkopieren ein Lock hat, also nicht
geschrieben werden kann.

In MySQL 5.1 und höher gilt jedoch

In most cases, ALTER TABLE works by making a temporary copy of the
original table. The alteration is performed on the copy, and then the
original table is deleted and the new one is renamed. [...]

In some cases, no temporary table is necessary:

Alterations that modify only table metadata and not table data can be
made immediately by altering the table's .frm file and not touching
table contents. The following changes are fast alterations that can be
made this way:

* Renaming a column or index.
* Changing the default value of a column.
* Changing the definition of an ENUM or SET column by adding new
enumeration or set members to the end of the list of valid member
values.


Die alten Bedenken gegen die Erweiterung eines ENUM- oder SET-Typen
wegen lange dauernder ALTER TABLE-Statements gelten also NICHT mehr,
vorausgesetzt es ist akzeptabel, daß neue Werte für den ENUM am Ende
der ENUM-Liste angehängt werden können, also keine interne
Umnummerierung notwendig ist.

Kris

Claus Reibenstein

unread,
Apr 9, 2010, 12:21:09 PM4/9/10
to
Kristian Köhntopp schrieb:

> ENUM hat in MySQL 5.1 einige Eigenschaften, die überraschend sind.

So?

> Zum Beispiel
>
> root@localhost [kris]> create table t (id integer unsigned not null
> primary key, e enum('a', 'b', 'c') not null ) engine = innodb;
> Query OK, 0 rows affected (0.21 sec)
>
>
> root@localhost [kris]> insert into t values (1, '');
> Query OK, 1 row affected, 1 warning (0.00 sec)
>
> Warning (Code 1265): Data truncated for column 'e' at row 1

Diese Warnung ist in der Tat überraschend.

> Obwohl t.e ein ENUM ist, das per Definition keinen Wert '' zuläßt

Falsch. Lies <http://dev.mysql.com/doc/refman/5.1/de/enum.html>.

> Bei der Kontrollausgabe sieht man bei der Konvertierung nach INTEGER,
> daß ein ENUM intern Zahl gespeichert wird, wobei dem ersten Wert die
> Zahl 1, dem nächsten die Zahl 2 und so weiter zugeordnet wird.

Dafür braucht man keine Kontrollausgabe. Ein Blick ins Manual genügt.

> Der Wert
> '', intern als 0 repräsentiert (und von NULL verschieden) wird immer
> zugelassen.

Eben hast Du noch das Gegenteil behauptet.

Gruß. Claus

Claus Reibenstein

unread,
Apr 9, 2010, 12:30:36 PM4/9/10
to
Karsten Wutzke schrieb:

> gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
> ENUM?

Definiere 'sinnvoll'.

Ein enum belegt je nach Anzahl der Werte 1 oder 2 Byte. Das absolute
Maximum sind somit 65.535 Werte.

Gruß. Claus

Claus Reibenstein

unread,
Apr 9, 2010, 12:14:36 PM4/9/10
to
Karsten Wutzke schrieb:

> gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
> ENUM?

Definiere 'sinnvoll'.

Ein enum belegt je nach Anzahl der Werte 1 oder 2 Byte. Das absolute

Maximum sind somit 65.535 Strings.

Gruß. Claus

Karsten Wutzke

unread,
Apr 12, 2010, 1:25:17 PM4/12/10
to
>
> > gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
> > ENUM?
>
> Definiere 'sinnvoll'.
>

Warum muss ich das? Meine Frage ist nun mal nicht anders. Deswegen
auch nicht ganz einfach zu beantworten.

Ich denke, je statischer die Werte sind, desto eher kann man die Größe
des ENUMs vernachlässigen (um mal eine Faustformel anzubringen).

Karsten

Karsten Wutzke

unread,
Apr 12, 2010, 1:35:12 PM4/12/10
to
On 8 Apr., 21:30, Andreas Scherbaum <ads-n...@wars-nicht.de> wrote:
> Hallo,

>
> Karsten Wutzke <kwut...@web.de> wrote:
>
> > gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
> > ENUM?
>
> > [...]
>
> > Die Liste wird eher selten geändert
>
> Selten oder gar nicht?

Selten. Es handelt sich nicht um eine völlig fixe Liste wie z.B. die
Abkürzungen der Staaten der USA.

> ENUMs machen imho nur Sinn, wenn sich die Liste wirklich nicht mehr
> verändert. Andernfalls muss man die Definition des ENUM anfassen - und
> kann eigentlich gleich eine weitere Tabelle nehmen.
>
> Deine Liste mit Ländercodes ist nun wirklich nicht statisch,
> aufgrund von irgendwelchen Gründen kommen da welche hinzu oder
> fallen weg. Nimm also besser eine Tabelle dafür ;-) Das
> vereinfacht die Pflege.
>

So gesehen muss ich ja dann bei nahezu statischen Listen automatisch
eine Tabelle nehmen. So einfach finde ich es aber nicht die Schwelle
für den Übergang zu finden. Ist z.B. die Datenmenge nicht allzu groß
und wird der ENUM nicht noch von anderen Tabellen aus referenziert
kann man durchaus auch argumentieren der Einfachheit halber einen ENUM
zu nehmen. Die Diskussion hierzu wird sich wohl immer im Kreis drehen.
Wichtig ist, dass die Pros und Cons bekannt sind. Entscheiden muss das
dann jeder selbst. Und ja: beides geht nach wie vor.

Karsten

Andreas Scherbaum

unread,
Apr 12, 2010, 5:05:36 PM4/12/10
to
Hallo,

Karsten Wutzke <kwu...@web.de> wrote:
> On 8 Apr., 21:30, Andreas Scherbaum <ads-n...@wars-nicht.de> wrote:
>>
>> Karsten Wutzke <kwut...@web.de> wrote:
>>
>> > gibt es ein sinnvolles Maximum für die Anzahl von Elementen in einem
>> > ENUM?
>>
>> > [...]
>>
>> > Die Liste wird eher selten geändert
>>
>> Selten oder gar nicht?
>
> Selten. Es handelt sich nicht um eine völlig fixe Liste wie z.B. die
> Abkürzungen der Staaten der USA.

Mal als Denkanstoß: die USA haben auch mal mit 13 Bundesstaaten angefangen.
Jetzt überleg dir, wie oft du dein ENUM hättest ändern müssen ;-)

Niels Braczek

unread,
Apr 13, 2010, 12:56:26 AM4/13/10
to
Karsten Wutzke schrieb:

>> Deine Liste mit Ländercodes ist nun wirklich nicht statisch,
>> aufgrund von irgendwelchen Gründen kommen da welche hinzu oder
>> fallen weg. Nimm also besser eine Tabelle dafür ;-) Das
>> vereinfacht die Pflege.
>>
>
> So gesehen muss ich ja dann bei nahezu statischen Listen automatisch
> eine Tabelle nehmen. So einfach finde ich es aber nicht die Schwelle
> für den Übergang zu finden. Ist z.B. die Datenmenge nicht allzu groß
> und wird der ENUM nicht noch von anderen Tabellen aus referenziert
> kann man durchaus auch argumentieren der Einfachheit halber einen ENUM
> zu nehmen.

Über ENUM kann man nachdenken, wenn die Liste der Werte unveränderlich
und vollständig ist. Staaten fallen gewiss nicht in diese Kategorie. Bei
Geschlecht zB. decken die Werte 'männlich', 'weiblich', 'beides',
'weder-noch' und 'unbekannt' alle Möglichkeiten ab und sind daher
Kandidaten für ein ENUM. Wenn jetzt allerdings verschiedene
Alien-Spezies unterschiedliche oder gar mehrere Werte für 'weder-noch'
haben, platzt auch diese 'vollständige' Liste. Daher halten sich
sinnvolle Einsatzgebiete für ENUM als DB-Datentyp IMNSHO in sehr engen
Grenzen.

MfG
Niels

--
| http://www.kolleg.de · Das Portal der Kollegs in Deutschland |
| http://www.bsds.de · BSDS Braczek Software- und DatenSysteme |
| Webdesign · Webhosting · e-Commerce · Joomla! Content Management |
------------------------------------------------------------------

Andreas Scherbaum

unread,
Apr 13, 2010, 5:41:25 AM4/13/10
to
Hallo,

Niels Braczek <nbra...@freenet.de> wrote:
> Karsten Wutzke schrieb:
>
>>> Deine Liste mit Ländercodes ist nun wirklich nicht statisch,
>>> aufgrund von irgendwelchen Gründen kommen da welche hinzu oder
>>> fallen weg. Nimm also besser eine Tabelle dafür ;-) Das
>>> vereinfacht die Pflege.
>>>
>>
>> So gesehen muss ich ja dann bei nahezu statischen Listen automatisch
>> eine Tabelle nehmen. So einfach finde ich es aber nicht die Schwelle
>> für den Übergang zu finden. Ist z.B. die Datenmenge nicht allzu groß
>> und wird der ENUM nicht noch von anderen Tabellen aus referenziert
>> kann man durchaus auch argumentieren der Einfachheit halber einen ENUM
>> zu nehmen.
>
> Über ENUM kann man nachdenken, wenn die Liste der Werte unveränderlich
> und vollständig ist. Staaten fallen gewiss nicht in diese Kategorie. Bei
> Geschlecht zB. decken die Werte 'männlich', 'weiblich', 'beides',
> 'weder-noch' und 'unbekannt' alle Möglichkeiten ab und sind daher
> Kandidaten für ein ENUM. Wenn jetzt allerdings verschiedene
> Alien-Spezies unterschiedliche oder gar mehrere Werte für 'weder-noch'
> haben, platzt auch diese 'vollständige' Liste. Daher halten sich
> sinnvolle Einsatzgebiete für ENUM als DB-Datentyp IMNSHO in sehr engen
> Grenzen.

Ach, bis zu den Aliens müssen wir da gar nicht ausholen. Es reicht, wenn
wir bei uns auf der Erde bleiben:

http://de.wikipedia.org/wiki/Datenstandards_zur_Beschreibung_des_Geschlechts

(Ja, Wikipedia, aber alle relevanten Standards sind von dort verlinkt)

Christian Kirsch

unread,
Apr 28, 2010, 7:27:21 AM4/28/10
to
Niels Braczek schrieb:

> Über ENUM kann man nachdenken, wenn die Liste der Werte unveränderlich
> und vollständig ist. Staaten fallen gewiss nicht in diese Kategorie. Bei
> Geschlecht zB. decken die Werte 'männlich', 'weiblich', 'beides',
> 'weder-noch' und 'unbekannt' alle Möglichkeiten ab und sind daher
> Kandidaten für ein ENUM.

Meinst Du, dass ein Frau-zu-Mann-Transsexueller "beides", "weder-noch"
oder "unbekannt" ist - wohlgemerkt, *vor* der Operation?

Niels Braczek

unread,
Apr 28, 2010, 7:36:56 AM4/28/10
to
Christian Kirsch schrieb:

Er ist weiblich, wenn man die Geschlechtsorgane als Kriterium hernimmt.
Allein dieses Kriterium liegt der oben stehenden Einteilung zugrunde.
Aber das ist hier nebensächlich; ich denke, das Prinzip, wann Mengen für
ENUM geeignet sind, ist mit dem Beispiel deutlich(er) geworden.

Reply all
Reply to author
Forward
0 new messages