深入了解 MySQL 中的 ENUM 資料類型:完整範例指南

1. ENUM 類型概述

ENUM 類型是什麼?

MySQL 中的 ENUM(列舉)型別是一種資料型別,僅能儲存預先定義清單中的 一個 值。由於欄位只能保存特定的預設字串,這可確保資料一致性,並防止無效值被寫入。

舉例來說,當使用者從有限的選項(如性別或商品類別)中選擇一項時,使用 ENUM 類型即可省去不必要的錯誤檢查邏輯。以下是一個建立包含 ENUM 欄位的資料表範例:

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    category ENUM('食品', '衣料品', '家電', '家具') NOT NULL
);

在此範例中,category 欄位只能存放以下其中一個值:「食品」、「衣料品」、「家電」或「家具」。這有助於簡化資料管理,降低輸入錯誤的風險。

ENUM 的主要使用情境

ENUM 類型常見於以下情境:

  • 狀態管理:追蹤工作流程階段,如「未開始」、「進行中」或「完了」。
  • 類別定義:管理預先設定的選項,例如商品類別、使用者類型或職位。
  • 等級或層級分組:遊戲難度等級(「初級」、「中級」、「上級」)或商品評分(「良い」、「普通」、「悪い」)。

2. ENUM 的優點與缺點

優點

  1. 提升資料一致性
    ENUM 只允許出現在其預定清單中的值,確保資料處理的一致性。例如在管理性別時,只允許「男性」或「女性」這兩個已定義的值,避免無效輸入。
  2. 有效的儲存空間使用
    每個 ENUM 值在內部以整數索引儲存。因此相較於 VARCHAR,ENUM 佔用的儲存空間更少。例如「small」或「large」作為 VARCHAR 會佔較多空間,而 ENUM 會以數字索引的方式高效儲存。

缺點

  1. 缺乏彈性
    ENUM 的值是固定的。若要新增選項必須修改資料表結構,對於經常變動的資料集而言,ENUM 並不適合。
  2. 錯誤處理較為複雜
    若插入無效值,MySQL 可能拋出錯誤或將其存為空字串。這會增加開發人員除錯的難度。

3. 設定 ENUM 與實務應用

基本設定與錯誤處理

要設定 ENUM 型別,只需定義有效字串的清單。以下範例在資料表中定義了一個 ENUM 欄位:

CREATE TABLE shirts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    size ENUM('XS', 'S', 'M', 'L', 'XL') NOT NULL
);

此處 size 欄位僅接受「XS」、「S」、「M」、「L」或「XL」。若嘗試插入清單外的值(例如 ‘XXL’),會產生 Data truncated 錯誤,從而防止無效資料並維持一致性。

實務使用範例

以下範例使用 ENUM 來管理使用者角色,如「管理者」、「一般ユーザー」與「ゲスト」:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    role ENUM('管理者', '一般ユーザー', 'ゲスト') NOT NULL
);

使用 ENUM 欄位可輕鬆維持權限與角色的統一管理。

4. ENUM 的索引與 NULL 處理

使用索引

ENUM 值會根據其在清單中的位置分配整數索引。例如:

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    size ENUM('S', 'M', 'L', 'XL')
);

「S」的索引為 1,「M」的索引為 2,依此類推。這些索引可在 WHERE 子句中使用:

SELECT * FROM products WHERE size = 2;

此查詢會取得 size 為「M」的記錄。

處理 NULL 與空字串

若允許 NULL,欄位即使不在 ENUM 清單中,也可以存放 NULL 作為有效狀態。此外,若以空字串插入無效資料,會以索引 0 儲存,方便偵測錯誤輸入。

5. ENUM 的字元集與校對規則

如何設定字元集與校對規則

ENUM,像 CHAR 或 VARCHAR 一樣,支援字元集與校對規則的定義。這在處理多語言資料或排序操作時非常重要。範例:

CREATE TABLE documents (
    id INT AUTO_INCREMENT PRIMARY KEY,
    language ENUM('日本語', '英語', '中国語') 
        CHARACTER SET utf8 
        COLLATE utf8_general_ci
);

此範例指定 UTF-8 以及一般用途的校對規則。

6. 擴充 ENUM 與替代方案

擴展 ENUM 的技巧

由於 ENUM 缺乏對動態值的彈性,您可以加入「其他」選項,並將自由格式的輸入存放在另一個欄位:

ALTER TABLE products 
MODIFY COLUMN category ENUM('食品', '衣料品', '家電', '家具', 'その他') NOT NULL,
ADD COLUMN category_other VARCHAR(255) DEFAULT NULL;

這樣即可在保持結構的同時,儲存不在 ENUM 列表中的值。

替代資料類型:SET 或 VARCHAR

根據需求,替代方案包括:

  • SET 類型:從列表中儲存多項選擇。
  • VARCHAR:提供最大的彈性,無需預先定義限制。