Sök…


Varför ENUM?

ENUM ger ett sätt att tillhandahålla ett attribut för en rad. Attribut med ett litet antal icke-numeriska alternativ fungerar bäst. Exempel:

reply ENUM('yes', 'no')
gender ENUM('male', 'female', 'other', 'decline-to-state')

Värdena är strängar:

INSERT ... VALUES ('yes', 'female')
SELECT ... --> yes female

TINYINT som ett alternativ

Låt oss säga att vi har det

type ENUM('fish','mammal','bird')

Ett alternativ är

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

vilket är mycket som ett många-till-många-bord.

Jämförelse, och om det är bättre eller sämre än ENUM:

  • (värre) INSERT: måste leta upp type
  • (sämre) VÄLJ: måste gå med i JOIN för att få strängen (ENUM ger dig strängen utan ansträngning)
  • (bättre) Lägga till nya typer: Infoga bara i den här tabellen. Med ENUM måste du göra en ALTER-TABELL.
  • (samma) Endera tekniken (för upp till 255 värden) tar bara 1 byte.
  • (blandat) Det finns också en fråga om dataintegritet: TINYINT medger ogiltiga värden; ENUM ställer in dem till ett speciellt tomsträngsvärde (såvida inte strikt SQL-läge är aktiverat, i vilket fall de avvisas). Bättre dataintegritet kan uppnås med TINYINT genom att göra det till en utländsk nyckel till en uppslagstabell: som, med lämpliga frågor / sammanfogningar, men det finns fortfarande de lilla kostnaderna för att nå den andra tabellen. ( FOREIGN KEYs är inte gratis.)

VARCHAR som ett alternativ

Låt oss säga att vi har det

type ENUM('fish','mammal','bird')

Ett alternativ är

type VARCHAR(20)  COMENT "fish, bird, etc"

Detta är ganska öppet genom att nya typer läggs till.

Jämförelse, och om det är bättre eller sämre än ENUM:

  • (samma) INSERT: ange bara strängen
  • (sämre?) På INSERT kommer en skrivfel att bli obemärkt
  • (samma) VÄLJ: den aktuella strängen returneras
  • (värre) Mycket mer utrymme förbrukas

Lägga till ett nytt alternativ

ALTER TABLE tbl MODIFY COLUMN type ENUM('fish','mammal','bird','insect');

anteckningar

  • Som med alla fall av MODIFY COLUMN, måste du inkludera NOT NULL och alla andra kval som tidigare fanns, annars kommer de att gå förlorade.
  • Om du lägger till i slutet av listan och listan är under 256 objekt görs ALTER genom att bara ändra schemat. Det är att det inte kommer att finnas en lång tabellkopia. (Gamla versioner av MySQL hade inte denna optimering.)

NULL vs INTE NULL

Exempel på vad som händer när NULL och ”dåligt värde” lagras i nollbara och inte nullable kolumner. Visar också användning av casting till numerisk via +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)

Vad finns i tabellen efter dessa insatser. Detta använder "+0" för att skicka till numeriskt för att se vad som är lagrat.

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)


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow