MySQL
ENUM
Suche…
Warum ENUM?
ENUM bietet eine Möglichkeit, ein Attribut für eine Zeile bereitzustellen. Attribute mit einer kleinen Anzahl nicht numerischer Optionen funktionieren am besten. Beispiele:
reply ENUM('yes', 'no')
gender ENUM('male', 'female', 'other', 'decline-to-state')
Die Werte sind Strings:
INSERT ... VALUES ('yes', 'female')
SELECT ... --> yes female
TINYINT als Alternative
Sagen wir, wir haben
type ENUM('fish','mammal','bird')
Eine Alternative ist
type TINYINT UNSIGNED
Plus
CREATE TABLE AnimalTypes (
type TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL COMMENT "('fish','mammal','bird')",
PRIMARY KEY(type),
INDEX(name)
) ENGINE=InnoDB
Das ist sehr ähnlich wie ein Many-to-Many-Tisch.
Vergleich und ob besser oder schlechter als ENUM:
- (schlechter) INSERT: müssen den
type
nachschlagen - (schlechter) SELECT: Sie müssen sich mit JOIN verbinden, um die Zeichenfolge zu erhalten (ENUM gibt Ihnen die Zeichenfolge ohne Aufwand).
- (besser) Hinzufügen neuer Typen: Einfach in diese Tabelle einfügen. Mit ENUM müssen Sie eine ALTER TABLE ausführen.
- (gleich) Beide Verfahren (für bis zu 255 Werte) benötigen nur 1 Byte.
- (gemischt) Es gibt auch ein Problem der Datenintegrität:
TINYINT
ungültige Werte zu.ENUM
setzt sie jedoch auf einen speziellen Leerzeichenfolgenwert (sofern der strikte SQL-Modus nicht aktiviert ist; in diesem Fall werden sie abgelehnt). Bessere Datenintegrität kann mitTINYINT
werden, indem aus einem Fremdschlüssel eine Lookup-Tabelle erstellt wird, die bei entsprechenden Abfragen /TINYINT
mit demTINYINT
auf die andere Tabelle verbunden ist. (FOREIGN KEYs
sind nicht frei.)
VARCHAR als Alternative
Sagen wir, wir haben
type ENUM('fish','mammal','bird')
Eine Alternative ist
type VARCHAR(20) COMENT "fish, bird, etc"
Dies ist insofern recht offen, als neue Typen trivial hinzugefügt werden.
Vergleich und ob besser oder schlechter als ENUM:
- (gleich) INSERT: einfach die Zeichenfolge angeben
- (schlechter?) Bei INSERT wird ein Tippfehler unbemerkt bleiben
- (gleich) SELECT: Die aktuelle Zeichenfolge wird zurückgegeben
- (schlechter) Es wird viel mehr Speicherplatz verbraucht
Eine neue Option hinzufügen
ALTER TABLE tbl MODIFY COLUMN type ENUM('fish','mammal','bird','insect');
Anmerkungen
- Wie in allen Fällen von MODIFY COLUMN müssen Sie
NOT NULL
und alle anderen bereits vorhandenen Qualifikationsmerkmale angeben. - Wenn Sie am Ende der Liste hinzufügen und die Liste
ALTER
als 256 Elemente enthält, wird derALTER
durch einfaches Ändern des Schemas ausgeführt. Das heißt, es wird keine lange Tabellenkopie geben. (Alte Versionen von MySQL hatten diese Optimierung nicht.)
NULL vs. NOT NULL
Beispiele dafür, was passiert, wenn NULL und 'bad-value' in null- und nicht nullfähige Spalten gespeichert werden Zeigt auch die Verwendung des Gusses über +0
.
CREATE TABLE enum (
e ENUM('yes', 'no') NOT NULL,
enull ENUM('x', 'y', 'z') NULL
);
INSERT INTO enum (e, enull)
VALUES
('yes', 'x'),
('no', 'y'),
(NULL, NULL),
('bad-value', 'bad-value');
Query OK, 4 rows affected, 3 warnings (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 3
mysql>SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1048 | Column 'e' cannot be null |
| Warning | 1265 | Data truncated for column 'e' at row 4 |
| Warning | 1265 | Data truncated for column 'enull' at row 4 |
+---------+------+--------------------------------------------+
3 rows in set (0.00 sec)
Was steht in der Tabelle nach diesen Einsätzen? Dies verwendet "+0", um in numerische Werte umzuwandeln, was gespeichert ist.
mysql>SELECT e, e+0 FROM enum;
+-----+-----+
| e | e+0 |
+-----+-----+
| yes | 1 |
| no | 2 |
| | 0 | -- NULL
| | 0 | -- 'bad-value'
+-----+-----+
4 rows in set (0.00 sec)
mysql>SELECT enull, enull+0 FROM enum;
+-------+---------+
| enull | enull+0 |
+-------+---------+
| x | 1 |
| y | 2 |
| NULL | NULL |
| | 0 | -- 'bad-value'
+-------+---------+
4 rows in set (0.00 sec)