MySQL - 列舉型別



ENUM(列舉)是一種使用者定義的資料型別,它將值列表儲存為字串。這些值在定義 ENUM 列時指定。使用者可以在將值插入此列時從此預定義列表中選擇值。

在 ENUM 列中定義的每個字串值都隱式分配一個從 1 開始的數值。MySQL 在內部使用這些數值來表示 ENUM 值。

MySQL ENUM 資料型別

MySQL ENUM 資料型別允許您在插入或更新操作期間從預定義列表中選擇一個或多個值。選定的值作為字串儲存在表中,當您從 ENUM 列檢索資料時,這些值將以人類可讀的格式呈現。

ENUM 列可以接受各種資料型別的值,包括整數、浮點數、十進位制數和字串。但是,在內部,MySQL 會根據其預定義列表將這些值轉換為最接近的匹配 ENUM 值。

語法

以下是定義列上 ENUM 資料型別的語法:

CREATE TABLE table_name (  
   Column1,  
   Column2 ENUM ('value1','value2','value3', ...),  
   Column3...  
);

注意:列舉列最多可以有 65,535 個值。

ENUM 的屬性

MySQL 中的 ENUM 資料型別具有三個屬性。下面描述了相同的內容:

  • 預設值 - 列舉資料型別的預設值為 NULL。如果在插入時未為列舉欄位提供值,則將插入 Null 值。

  • NULL - 如果為列舉欄位設定此屬性,則其工作方式與 DEFAULT 值相同。如果設定,索引值始終為 NULL。

  • NOT NULL - 如果為列舉欄位設定此屬性,並且在插入時未提供值,則 MySQL 將生成警告訊息。

示例

首先,讓我們建立一個名為 STUDENTS 的表。在此表中,我們使用以下查詢在 BRANCH 列中指定 ENUM 字串物件:

CREATE TABLE STUDENTS (
   ID int NOT NULL AUTO_INCREMENT,
   NAME varchar(30) NOT NULL,
   BRANCH ENUM ('CSE', 'ECE', 'MECH'),
   FEES int NOT NULL,
   PRIMARY KEY (ID)
);

以下是獲得的輸出:

Query OK, 0 rows affected (0.04 sec)

現在,我們檢索 STUDENTS 表的結構,顯示“BRANCH”欄位具有列舉資料型別:

DESCRIBE STUDENTS;

輸出表明 BRANCH 欄位的資料型別為 ENUM,它儲存值 ('CSE', 'ECE', 'MECH'):

欄位 型別 Null 預設值 額外
ID int NO PRI NULL auto_increment
NAME varchar(30) NO NULL
BRANCH enum('CSE','ECE','MECH') YES NULL
FEES int NO NULL

現在,讓我們使用以下 INSERT 查詢將記錄插入 STUDENTS 表中:

INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES
('Anirudh', 'CSE', 500000),
('Yuvan', 'ECE', 350000),
('Harris', 'MECH', 400000);

在這些插入查詢中,我們對“BRANCH”欄位使用了值 ('CSE', 'ECE' 和 'MECH'),這些都是有效的列舉值。因此,查詢在沒有任何錯誤的情況下執行:

Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

使用以下查詢,我們可以顯示錶中的所有值:

SELECT * FROM STUDENTS;

以下是 STUDENTS 表的記錄:

ID NAME BRANCH FEES
1 Anirudh CSE 500000
2 Yuvan ECE 350000
3 Harris MECH 400000

使用數值 ENUM 值插入記錄

我們可以使用相應的數字索引將列舉列表值插入表的 ENUM 列中。數字索引從 1 開始,而不是從 0 開始。

示例

在下面的查詢中,我們使用其數字索引將列舉列表中的值“CSE”插入“BRANCH”列。由於“CSE”位於 ENUM 列表中的位置 1,因此我們在查詢中使用 1 作為數字索引。

INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES 
('Devi', 1, 380000);

輸出

插入查詢在沒有任何錯誤的情況下執行:

Query OK, 1 row affected (0.01 sec)

驗證

讓我們使用以下查詢檢索表的所有記錄來驗證以上插入是否成功:

SELECT * FROM STUDENTS;

顯示的 STUDENTS 表如下:

ID NAME BRANCH FEES
1 Anirudh CSE 500000
2 Yuvan ECE 350000
3 Harris MECH 400000
4 Devi CSE 380000

插入無效記錄

在 MySQL 中,如果我們嘗試將值插入具有 ENUM 資料型別的列中,該值與任何指定的列舉值都不匹配,則會導致錯誤。

示例

在以下查詢中,我們引用了列舉列表中的第 6 個值,該值不存在。因此,以下查詢將生成錯誤:

INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES 
('Thaman', 6, 200000); 

輸出

正如我們所看到的輸出,生成了一個錯誤,並且沒有插入新記錄:

ERROR 1265 (01000): Data truncated for column 'BRANCH' at row 1

按數值 ENUM 值過濾記錄

在 MySQL 中,您可以根據字串值或數字索引從 ENUM 列檢索記錄。數字索引從 1 開始,而不是 0。

示例

列舉列表中數字索引 1 為“CSE”。因此,以下查詢將獲取 BRANCH 列包含值為“CSE”的記錄。

SELECT * FROM STUDENTS WHERE BRANCH = 1;

輸出

生成的輸出顯示“BRANCH”列包含值“CSE”的記錄:

ID NAME BRANCH FEES
1 Anirudh CSE 500000
4 Devi CSE 380000

按人類可讀的 ENUM 值過濾記錄

列舉列表有時可能包含大量值。記住列表中每個值的數字索引可能很困難。在這種情況下,在查詢中使用列舉項的可讀字串值來檢索基於列舉欄位值的記錄會更加方便。

示例

在下面的查詢中,我們過濾了 BRANCH 列包含值“Mech”的記錄。

SELECT * FROM STUDENTS WHERE BRANCH = "MECH";

輸出

以下是獲得的輸出:

ID NAME BRANCH FEES
3 Harris MECH 400000

ENUM 資料型別的缺點

以下是 MySQL 中列舉資料型別的缺點:

  • 如果我們希望修改列舉列表中的值,我們需要使用 ALTER TABLE 命令重新建立整個表,這在使用的資源和時間方面都非常昂貴。

  • 獲取完整的列舉列表非常複雜,因為我們需要訪問 inform_schema 資料庫。

  • 列舉值不能與表示式一起使用。例如,以下 CREATE 語句將返回錯誤,因為它使用了 CONCAT() 函式來建立列舉值:

CREATE TABLE Students (  
   ID int PRIMARY KEY AUTO_INCREMENT,   
   NAME varchar(30),   
   BRANCH ENUM('CSE', CONCAT('ME','CH'))
);

使用者變數不能用於列舉值。例如,請看以下查詢:

mysql> SET @mybranch = 'EEE';  
mysql> CREATE TABLE Students (  
   ID int PRIMARY KEY AUTO_INCREMENT,   
   NAME varchar(30),   
   BRANCH ENUM('CSE', 'MECH', @mybranch)
);

建議不要使用數字值作為列舉值。

使用客戶端程式的列舉資料型別

我們也可以使用客戶端程式建立列舉資料型別的列。

語法

要透過 PHP 程式建立列舉資料型別的列,我們需要使用 mysqli 函式 query() 執行“CREATE TABLE”語句,如下所示:

$sql = 'CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ("CSE", "ECE", "MECH"), FEES int NOT NULL, PRIMARY KEY (ID))';
$mysqli->query($sql);

要透過 JavaScript 程式建立列舉資料型別的列,我們需要使用 mysql2 庫的 query() 函式執行“CREATE TABLE”語句,如下所示:

sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ('CSE', 'ECE', 'MECH'), FEES int NOT NULL, PRIMARY KEY (ID) )";
con.query(sql);

要透過 Java 程式建立列舉資料型別的列,我們需要使用 JDBC 函式 execute() 執行“CREATE TABLE”語句,如下所示:

String sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM (\"CSE\", \"ECE\", \"MECH\"), FEES int NOT NULL, PRIMARY KEY (ID))";
statement.execute(sql);

要透過 Python 程式建立列舉資料型別的列,我們需要使用 MySQL Connector/Pythonexecute() 函式執行“CREATE TABLE”語句,如下所示:

sql = 'CREATE TABLE STUDENTS( ID int NOT NULL AUTO_INCREMENT,  NAME varchar(30) NOT NULL,  BRANCH ENUM ('CSE', 'ECE', 'MECH'),  FEES int NOT NULL,  PRIMARY KEY (ID)  )'    
cursorObj.execute(sql)

示例

以下是程式:

$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$dbname = 'TUTORIALS';
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($mysqli->connect_errno) {
    printf("Connect failed: %s
", $mysqli->connect_error); exit(); } //printf('Connected successfully.
'); //create table with boolean column $sql = 'CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ("CSE", "ECE", "MECH"), FEES int NOT NULL, PRIMARY KEY (ID))'; $result = $mysqli->query($sql); if ($result) { printf("Table created successfully...!\n"); } //insert data into created table $q = "INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES ('Anirudh', 'CSE', 500000), ('Yuvan', 'ECE', 350000)"; if ($res = $mysqli->query($q)) { printf("Data inserted successfully...!\n"); } //now display the table records $s = "SELECT BRANCH FROM STUDENTS"; if ($r = $mysqli->query($s)) { printf("Select query executed successfully...!\n"); printf("following records belongs to Enum datatypes: \n"); while ($row = $r->fetch_assoc()) { printf(" Branch Name: %s", $row["BRANCH"]); printf("\n"); } } else { printf('Failed'); } $mysqli->close();

輸出

獲得的輸出如下:

Table created successfully...!
Data inserted successfully...!
Select query executed successfully...!
following records belongs to Enum datatypes:
 Branch Name: CSE
 Branch Name: ECE         
var mysql = require("mysql2");
var con = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "password",
}); //Connecting to MySQL

con.connect(function (err) {
  if (err) throw err;
  //   console.log("Connected successfully...!");
  //   console.log("--------------------------");
  sql = "USE TUTORIALS";
  con.query(sql);

  //create a customers that accepts one column enum type.
  sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM ('CSE', 'ECE', 'MECH'), FEES int NOT NULL, PRIMARY KEY (ID) )";
  con.query(sql);

  //insert data into created table
  sql ="INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES ('Anirudh', 'CSE', 500000),  ('Yuvan', 'ECE', 350000)";
  con.query(sql);
  //select datatypes of branch
  sql = `SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'STUDENTS' AND COLUMN_NAME = 'BRANCH'`;
  con.query(sql, function (err, result) {
    if (err) throw err;
    console.log(result);
  });
});  

輸出

產生的輸出如下:

[ { DATA_TYPE: 'enum' } ]
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Enum {
   public static void main(String[] args) {
      String url = "jdbc:mysql://:3306/TUTORIALS";
      String username = "root";
      String password = "password";
      try {
         Class.forName("com.mysql.cj.jdbc.Driver");
         Connection connection = DriverManager.getConnection(url, username, password);
         Statement statement = connection.createStatement();
         System.out.println("Connected successfully...!");

         //ENUM data types...!;
         String sql = "CREATE TABLE STUDENTS (ID int NOT NULL AUTO_INCREMENT, NAME varchar(30) NOT NULL, BRANCH ENUM (\"CSE\", \"ECE\", \"MECH\"), FEES int NOT NULL, PRIMARY KEY (ID))";
         statement.execute(sql);
         System.out.println("column of a ENUM type created successfully...!");
         ResultSet resultSet = statement.executeQuery("DESCRIBE STUDENTS");
         while (resultSet.next()){
            System.out.println(resultSet.getString(1)+" "+resultSet.getString(2));
         }
         connection.close();
      } catch (Exception e) {
         System.out.println(e);
      }
   }
}  

輸出

獲得的輸出如下所示:

Connected successfully...!
column of a ENUM type created successfully...!
ID int
NAME varchar(30)
BRANCH enum('CSE','ECE','MECH')
FEES int  
import mysql.connector
# Establishing the connection
connection = mysql.connector.connect(
    host='localhost',
    user='root',
    password='password',
    database='tut'
)
# Creating a cursor object
cursorObj = connection.cursor()
# Create table with enum column
sql = '''
CREATE TABLE STUDENTS (
ID int NOT NULL AUTO_INCREMENT,
NAME varchar(30) NOT NULL,
BRANCH ENUM ('CSE', 'ECE', 'MECH'),
FEES int NOT NULL,
PRIMARY KEY (ID)
);
'''
cursorObj.execute(sql)
print("The table is created successfully!")
# Data to be inserted
data_to_insert = [
    ('Anirudh', 'CSE', 500000),
    ('Yuvan', 'ECE', 350000),
    ('Harris', 'MECH', 400000)
]
# Insert data into the created table
insert_query = "INSERT INTO STUDENTS (NAME, BRANCH, FEES) VALUES (%s, %s, %s)"
cursorObj.executemany(insert_query, data_to_insert)
# Commit the changes after the insert operation
connection.commit()
print("Rows inserted successfully.")
# Now display the table records
select_query = "SELECT * FROM STUDENTS"
cursorObj.execute(select_query)
result = cursorObj.fetchall()
print("Table Data:")
for row in result:
    print(row)
cursorObj.close()
connection.close()  

輸出

以下是上述程式碼的輸出:

The table is created successfully!
Rows inserted successfully.
Table Data:
(1, 'Anirudh', 'CSE', 500000)
(2, 'Yuvan', 'ECE', 350000)
(3, 'Harris', 'MECH', 400000)
廣告