ENUM
是一個字串物件,其值是從表格建立時在欄位規格中明確列舉的允許值清單中選擇的。
請參閱第 13.3.1 節「字串資料類型語法」,以了解 ENUM
類型語法和長度限制。
ENUM
類型具有以下優點:
在欄位具有一組有限的可能值的情況下,可進行精簡的資料儲存。您指定為輸入值的字串會自動編碼為數字。有關
ENUM
類型的儲存需求,請參閱第 13.7 節「資料類型儲存需求」。可讀取的查詢和輸出。數字會在查詢結果中轉譯回對應的字串。
以及以下需要考慮的潛在問題:
列舉值必須是帶引號的字串文字。例如,您可以像這樣建立具有 ENUM
欄位的表格:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),
('polo shirt','small');
SELECT name, size FROM shirts WHERE size = 'medium';
+---------+--------+
| name | size |
+---------+--------+
| t-shirt | medium |
+---------+--------+
UPDATE shirts SET size = 'small' WHERE size = 'large';
COMMIT;
如果將值為 'medium'
的 100 萬列插入此表格,則需要 100 萬位元組的儲存空間,而不是將實際字串 'medium'
儲存在 VARCHAR
欄位中時的 600 萬位元組。
每個列舉值都有一個索引。
欄位規格中列出的元素會被指派索引編號,從 1 開始。
空字串錯誤值的索引值為 0。這表示您可以使用下列
SELECT
陳述式來尋找已指派無效ENUM
值的列:mysql> SELECT * FROM tbl_name WHERE enum_col=0;
NULL
值的索引為NULL
。此處的 「索引」一詞是指列舉值清單中的位置。它與表格索引無關。
例如,指定為 ENUM('Mercury', 'Venus', 'Earth')
的欄位可以具有此處顯示的任何值。每個值的索引也會顯示。
值 | 索引 |
---|---|
NULL |
NULL |
'' |
0 |
'Mercury' |
1 |
'Venus' |
2 |
'Earth' |
3 |
ENUM
欄位最多可以有 65,535 個不同的元素。
如果您在數值環境中擷取 ENUM
值,則會傳回欄位值的索引。例如,您可以像這樣從 ENUM
欄位擷取數值:
mysql> SELECT enum_col+0 FROM tbl_name;
諸如 SUM()
或 AVG()
等期望數值引數的函數,會在必要時將引數轉換為數字。對於 ENUM
值,計算中使用索引編號。
建立表格時,會自動從表格定義中的 ENUM
成員值刪除尾隨空格。
擷取時,儲存在 ENUM
欄位中的值會使用欄位定義中使用的字母大小寫顯示。請注意,可以為 ENUM
欄位指派字元集和排序規則。對於二進位或區分大小寫的排序規則,在將值指派給欄位時,會考慮字母大小寫。
如果您將數字儲存到 ENUM
欄位中,則該數字會被視為可能值的索引,並且儲存的值是具有該索引的列舉成員。(但是,這不適用於 LOAD DATA
,它將所有輸入都視為字串。)如果數值帶引號,則如果列舉值清單中沒有相符的字串,則仍會將其解譯為索引。基於這些原因,不建議定義具有看起來像數字的列舉值的 ENUM
欄位,因為這很容易造成混淆。例如,下列欄位具有字串值為 '0'
、'1'
和 '2'
的列舉成員,但數值索引值為 1
、2
和 3
:
numbers ENUM('0','1','2')
如果您儲存 2
,則會將其解譯為索引值,並變成 '1'
(索引為 2 的值)。如果您儲存 '2'
,它會與列舉值相符,因此會儲存為 '2'
。如果您儲存 '3'
,它不與任何列舉值相符,因此會將其視為索引,並變成 '2'
(索引為 3 的值)。
mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql> SELECT * FROM t;
+---------+
| numbers |
+---------+
| 1 |
| 2 |
| 2 |
+---------+
若要判斷 ENUM
欄位的所有可能值,請使用 SHOW COLUMNS FROM
並剖析輸出 tbl_name
LIKE 'enum_col
'Type
欄位中的 ENUM
定義。
在 C API 中,ENUM
值會以字串形式傳回。如需有關使用結果集 Metadata 將它們與其他字串區分的相關資訊,請參閱C API 基本資料結構。
在某些情況下,列舉值也可以是空字串 (''
) 或 NULL
:
如果您將無效的值插入
ENUM
中(也就是說,一個不在允許值列表中的字串),則會插入空字串作為特殊的錯誤值。此字串可以透過其數值為 0 來區分於「「正常」」空字串。關於列舉值的數值索引的詳細資訊,請參閱列舉常值的索引值。如果啟用了嚴格 SQL 模式,嘗試插入無效的
ENUM
值會導致錯誤。如果宣告
ENUM
資料行允許NULL
,則NULL
值對於該資料行是有效的值,且預設值為NULL
。如果宣告ENUM
資料行NOT NULL
,則其預設值為允許值列表中的第一個元素。
ENUM
值會根據其索引編號進行排序,這取決於列舉成員在資料行規格中列出的順序。例如,對於 ENUM('b', 'a')
而言,'b'
會在 'a'
之前排序。空字串會在非空字串之前排序,而 NULL
值會在所有其他列舉值之前排序。
為了防止在 ENUM
資料行上使用 ORDER BY
子句時出現意外的結果,請使用以下其中一種方法:
以字母順序指定
ENUM
列表。透過編碼
ORDER BY CAST(
或col
AS CHAR)ORDER BY CONCAT(
,確保資料行是按詞彙而非索引編號排序。col
)
列舉值不能是運算式,即使是求值為字串值的運算式也不行。
例如,這個 CREATE TABLE
陳述式無法運作,因為 CONCAT
函數不能用來建構列舉值。
CREATE TABLE sizes (
size ENUM('small', CONCAT('med','ium'), 'large')
);
您也不能使用使用者變數作為列舉值。這兩個陳述式無法運作。
SET @mysize = 'medium';
CREATE TABLE sizes (
size ENUM('small', @mysize, 'large')
);
我們強烈建議您不要使用數字作為列舉值,因為這樣並不會比使用適當的 TINYINT
或 SMALLINT
類型節省儲存空間,而且如果您錯誤地引用 ENUM
值,很容易混淆字串和基礎數字值(可能不一樣)。如果您確實使用數字作為列舉值,請務必將其括在引號中。如果省略引號,則該數字會被視為索引。請參閱列舉常值的處理,以了解即使是帶引號的數字也可能被錯誤地用作數值索引值。
定義中的重複值會導致警告,如果啟用了嚴格 SQL 模式,則會導致錯誤。