MySQL enum類型

在本教學中,您將學習如何使用MySQL ENUM數據類型定義存儲枚舉值的列。

MySQL ENUM數據類型簡介

在MySQL中,ENUM是一個字串對象,其值是從列創建時定義的允許值列表中選擇的。

ENUM數據類型提供以下優點:

  • 緊湊型數據存儲,MySQL ENUM使用數字索引(1,2,3,…)來表示字串值。
  • 可讀查詢和輸出。

要定義ENUM列,請使用以下語法:

CREATE TABLE table_name (
    ...
    col ENUM ('value1','value2','value3'),
    ...
);

在這種語法中,可以有三個以上的枚舉值。但是,將枚舉值的數量保持在20以下是一個很好的做法。

下麵來看看看下麵的例子。

假設我們必須存儲優先順序為:low, mediumhigh 的票據資訊。 要將priority列分配給ENUM類型,請使用以下CREATE TABLE語句:

USE testdb;

CREATE TABLE tickets (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(255) NOT NULL,
    priority ENUM('Low', 'Medium', 'High') NOT NULL
);

priority列只接受三個Low, Medium, High值。 在後臺,MySQL將每個枚舉成員映射到數字索引。在這種情況下,LowMediumHigh分別映射到1,23(注意:與數組不同,這不是從0開始的)。

插入MySQL ENUM值

要將數據插入ENUM列中,可以使用預定義列表中的枚舉值。 例如,以下語句在tickets表中插入一個新行。

INSERT INTO tickets(title, priority)
VALUES('Scan virus for computer A', 'High');

除了枚舉值之外,還可以使用枚舉成員的數字索引將數據插入ENUM列。 例如,以下語句插入優先順序為Low的新機票數據:

INSERT INTO tickets(title, priority)
VALUES('Upgrade Windows OS for all computers', 1);

在這個例子中,我們使用的值為:1,而不是使用Low枚舉值,因為Low被映射到1,這是可以接受的。

我們再向ticketa表添加一些行數據:

INSERT INTO tickets(title, priority)
VALUES('Install Google Chrome for Mr. John', 'Medium'),
      ('Create a new user for the new employee David', 'High');

因為我們將優先順序定義為NOT NULL列,當插入新行而不指定優先順序列的值時,MySQL將使用第一個枚舉成員作為默認值。

參見下列語句聲明:

INSERT INTO tickets(title)
VALUES('Refresh the computer of Ms. Lily');

在非嚴格的SQL模式下,如果在ENUM列中插入無效值,MySQL將使用空字元串'',插入數字索引為0。 如果啟用了嚴格的SQL模式,嘗試插入無效的ENUM值將導致錯誤。

請注意,如果ENUM列定義為可空列,則可以接受NULL值。

過濾MySQL ENUM值

以下語句查詢獲得所有高優先順序機票:

SELECT
    *
FROM
    tickets
WHERE
    priority = 'High';

執行上面查詢語句,得到以下結果 -

+----+----------------------------------------------+----------+
| id | title                                        | priority |
+----+----------------------------------------------+----------+
|  1 | Scan virus for computer A                    | High     |
|  4 | Create a new user for the new employee David | High     |
+----+----------------------------------------------+----------+
2 rows in set

由於枚舉成員’High‘映射到3,因此以下查詢返回相同的結果集:

SELECT
    *
FROM
    tickets
WHERE
    priority = 3;

也可以使用比較運算符來查詢,比如 -

SELECT
    *
FROM
    tickets
WHERE
    priority >= 2;

排序MySQL ENUM值

MySQL根據索引號排序ENUM值。 因此,成員的順序取決於它們在枚舉列表中的定義。

以下查詢選擇門票並按優先順序從高到低進行排序:

SELECT
    title, priority
FROM
    tickets
ORDER BY priority DESC;

執行上面查詢語句,得到以下結果 -

+----------------------------------------------+----------+
| title                                        | priority |
+----------------------------------------------+----------+
| Scan virus for computer A                    | High     |
| Create a new user for the new employee David | High     |
| Install Google Chrome for Mr. John           | Medium   |
| Upgrade Windows OS for all computers         | Low      |
| Refresh the computer of Ms. Lily             | Low      |
+----------------------------------------------+----------+
5 rows in set

在創建列時,按順序定義枚舉值是一個很好的做法。

MySQL ENUM的缺點

MySQL ENUM有以下缺點:

  • 更改枚舉成員需要使用ALTER TABLE語句重建整個表,這在資源和時間方面是昂貴的。
  • 獲取完整的枚舉列表很複雜,因為需要訪問information_schema資料庫:
    SELECT
      column_type
    FROM
      information_schema.COLUMNS
    WHERE
      TABLE_NAME = 'tickets'
          AND COLUMN_NAME = 'priority';
    
  • 遷移到其他RDBMS可能是一個問題,因為ENUM不是SQL標準的,並且資料庫系統不支持它。
  • 向枚舉列表添加更多屬性是不可能的。假設您要為每個優先順序添加服務協議,例如High(24h)Medium(1-2天)Low(1周),則不可以使用ENUM類型的。 在這種情況下,需要有一個單獨的表來存儲優先順序列表,例如priority(id,name,sort_order,description),並且通過引用了priority表的id字段的priority_id來替換tickets表中的priority字段。
  • 與查找表(priorities)相比,枚舉列表不可重用。 例如,如果要創建一個名為tasks並且要重用優先順序列表的新表,則是不可能的。

在本教學中,我們向您介紹了MySQL ENUM數據類型以及如何使用它來定義存儲枚舉值的列。


上一篇: MySQL數據類型 下一篇: MySQL技巧