ENUM
是一種字串物件,其值是從表格建立時在資料行規格中明確列舉的允許值清單中選取的。
請參閱第 13.3.1 節「字串資料類型語法」,以瞭解 ENUM
類型語法和長度限制。
ENUM
類型具有以下優點
在資料行具有有限的一組可能值的情況下,可壓縮資料儲存。您指定為輸入值的字串會自動編碼為數字。請參閱第 13.7 節「資料類型儲存需求」,以瞭解
ENUM
類型的儲存需求。可讀取的查詢和輸出。這些數字在查詢結果中會轉換回對應的字串。
以及需要考量的這些潛在問題
列舉值必須是加上引號的字串常值。例如,您可以建立具有 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;
將 100 萬列資料插入到此表格中,且值為 'medium'
,則需要 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
值會以字串的形式傳回。如需使用結果集中繼資料將它們與其他字串區分開來的資訊,請參閱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 模式,則會導致錯誤。