mysql之ENUM列舉型別

小亮520cl發表於2015-03-13

本節主要內容:
MySQL資料型別之列舉型別ENUM

MySQL資料庫提供針對儲存的一種特殊資料型別:列舉型別ENUM,這種資料型別可以給予我們更多提高效能、降低儲存容量和降低程式程式碼理解的技巧,前面介紹了首先介紹了四種資料型別的特性總結,其後又分別介紹了布林型別BOOL或稱布林型別BOOLEAN,以及後續會再單獨介紹集合型別SET。

本文詳細介紹集合型別enum測試過程與總結,加深對集合型別enum的理解記憶。
n  列舉型別ENUM
a).表ops_enum結構
執行資料庫表mysqlops_enum建立的SQL語句:
 

複製程式碼程式碼示例:
root@localhost : test 11:22:29> CREATE TABLE Mysqlops_enum(ID INT NOT NULL AUTO_INCREMENT,
    ->  Job_type    ENUM('DBA','SA','Coding Engineer','JavaScript','NA','QA','','other') NOT NULL,
    ->  Work_City ENUM('shanghai','beijing','hangzhou','shenzhen','guangzhou','other') NOT NULL DEFAULT 'shanghai',
    ->  PRIMARY KEY(ID)
    ->  )ENGINE=InnoDB CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
 
Query OK, 0 rows affected (0.00 sec)
 

執行查詢資料庫表mysqlops_enum結構的SQL語句:
 

複製程式碼程式碼示例:
root@localhost : test 11:23:31> SHOW CREATE TABLE Mysqlops_enum\G
 
*************************** 1. row ***************************
 
       Table: Mysqlops_enum
 
Create Table: CREATE TABLE `Mysqlops_enum` (
 
  `ID` int(11) NOT NULL AUTO_INCREMENT,
 
  `Job_type` enum('DBA','SA','Coding Engineer','JavaScript','NA','QA','','other') NOT NULL,
 
  `Work_City` enum('shanghai','beijing','hangzhou','shenzhen','guangzhou','other') NOT NULL DEFAULT 'shanghai',
 
  PRIMARY KEY (`ID`)
 
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
 
1 row in set (0.00 sec)
 

小結:
     為方便測試列舉型別,如何處理欄位定義的預設值、是否允許為NULL和空值的情況,我們定義了2個列舉型別的欄位名,經過對比建立與查詢資料庫中表的結構資訊,沒有發現MySQL資料庫預設修改任何資訊。
b). 寫入不同型別的測試資料
寫入一條符合列舉型別定義的記錄值:
 

複製程式碼程式碼示例:
root@localhost : test 11:22:35> INSERT INTO Mysqlops_enum(ID,Job_type,Work_City) VALUES(1,'QA','shanghai'); 
Query OK, 1 row affected (0.00 sec)

測試第二個列舉型別字Work_City是否允許為空記錄值:
 

複製程式碼程式碼示例:
root@localhost : test 11:22:42> INSERT INTO Mysqlops_enum(ID,Job_type,Work_City) VALUES(2,'NA',''); 
Query OK, 1 row affected, 1 warning (0.00 sec)
 
root@localhost : test 11:22:48> SHOW WARNINGS;
 
+---------+------+------------------------------------------------+
 
| Level   | Code | Message              |
 
+---------+------+------------------------------------------------+
 
| Warning | 1265 | Data truncated for column 'Work_City' at row 1 |
 
+---------+------+------------------------------------------------+
 
1 row in set (0.00 sec)
 

測試第二個列舉型別欄位Work_City是否允許儲存NULL值:
 

複製程式碼程式碼示例:
root@localhost : test 11:22:53> INSERT INTO Mysqlops_enum(ID,Job_type,Work_City) VALUES(3,'Other',NULL); 
ERROR 1048 (23000): Column 'Work_City' cannot be null

測試第一個列舉型別欄位Job_type是否可以儲存空白值:
 

複製程式碼程式碼示例:
root@localhost : test 11:22:59> INSERT INTO Mysqlops_enum(ID,Job_type,Work_City) VALUES(4,'','hangzhou'); 
Query OK, 1 row affected (0.00 sec)

測試第二個列舉型別欄位Job_City如何處理沒有在定義中描述的值域第一個列舉型別欄位Work_Type的預設值沒指定情況下,會預設填寫那個值:
 

複製程式碼程式碼示例:
root@localhost : test 11:23:06> INSERT INTO Mysqlops_enum(ID,Work_City) VALUES(5,'ningbo'); 
Query OK, 1 row affected, 1 warning (0.00 sec)
 
root@localhost : test 11:23:13> SHOW WARNINGS;
 
+---------+------+------------------------------------------------+
 
| Level   | Code | Message              |
 
+---------+------+------------------------------------------------+
 
| Warning | 1265 | Data truncated for column 'Work_City' at row 1 |
 
+---------+------+------------------------------------------------+
 
1 row in set (0.00 sec)
 

測試第二個列舉型別欄位未插入資料的情況下,是否能使用上欄位定義中指定的預設值:
 

複製程式碼程式碼示例:
root@localhost : test 11:23:17> INSERT INTO Mysqlops_enum(ID,Job_type) VALUES(6,'DBA'); 
Query OK, 1 row affected (0.00 sec)

小結:
若是列舉型別欄位定義為非NULL,預設的SQL_MODE模式下,插入NULL值則會報錯,導致SQL語句執行失敗;若是沒有明確申明非NULL,則允許插入NULL值;
若是列舉型別欄位的列舉值中,沒有指定空格字元值,插入空格字元資料時,會出現資料截斷的警告資訊,但是SQL語句依然執行成功;
若是向列舉型別欄位插入未在定義列表中出現的資料,則會出現資料截斷的警告資訊,但是SQL語句依然執行成功;
若是列舉型別定義為非NULL,向資料庫表中插入新資料,但未指定列舉型別欄位的值,則使用列舉型別欄位定義申明的預設值,若是無顯示申明則是採用列舉型別欄位的列舉列表中第一個值作為預設值;
c). 查詢資料庫表mysqlops_enum的資料
查詢列舉型別資料庫表Mysqlops_enum所有的資料(註釋:兩個列舉型別欄位都是非NULL,所以截斷後的值為空格):
 

複製程式碼程式碼示例:
root@localhost : test 11:23:24> SELECT * FROM Mysqlops_enum;
 
+----+----------+-----------+
 
| ID | Job_type | Work_City |
 
+----+----------+-----------+
 
|  1 | QA       | shanghai  |
 
|  2 | NA       |           |
 
|  4 |          | hangzhou  |
 
|  5 | DBA      |           |
 
|  6 | DBA      | shanghai  |
 
+----+----------+-----------+
 
5 rows in set (0.00 sec)
 

驗證列舉型別欄位儲存的是資料對應的序列編號,而不是真實的字串值,且序列號是與列舉型別欄位值域列表中的順序有關:
 

複製程式碼程式碼示例:
root@localhost : test 11:23:57> SELECT * FROM Mysqlops_enum WHERE Work_City=0;
 
+----+----------+-----------+
 
| ID | Job_type | Work_City |
 
+----+----------+-----------+
 
|  2 | NA       |           |
 
|  5 | DBA      |           |
 
+----+----------+-----------+
 
2 rows in set (0.00 sec)
 
root@localhost : test 01:22:08> SELECT * FROM Mysqlops_enum WHERE Work_City=1;
 
+----+----------+-----------+
 
| ID | Job_type | Work_City |
 
+----+----------+-----------+
 
|  1 | QA       | shanghai  |
 
|  6 | DBA      | shanghai  |
 
+----+----------+-----------+
 
2 rows in set (0.00 sec)
 
root@localhost : test 02:40:31> SELECT * FROM Mysqlops_enum WHERE Work_City=2;
 
Empty set (0.00 sec)
 
root@localhost : test 02:40:33> SELECT * FROM Mysqlops_enum WHERE Work_City=3;
 
+----+----------+-----------+
 
| ID | Job_type | Work_City |
 
+----+----------+-----------+
 
|  4 |          | hangzhou  |
 
+----+----------+-----------+
 
1 row in set (0.01 sec)
 
root@localhost : test 02:40:34> SELECT * FROM Mysqlops_enum WHERE Work_City=4;
 
Empty set (0.00 sec)
 
root@localhost : test 02:40:36> SELECT * FROM Mysqlops_enum WHERE Work_City=5;
 
Empty set (0.00 sec)
 
root@localhost : test 02:40:37> SELECT * FROM Mysqlops_enum WHERE Work_City=6;
 
Empty set (0.00 sec)
 
root@localhost : test 04:29:07> SELECT * FROM Mysqlops_enum WHERE Job_type=7;
 
+----+----------+-----------+
 
| ID | Job_type | Work_City |
 
+----+----------+-----------+
 
|  4 |          | hangzhou  |
 
+----+----------+-----------+
 
1 row in set (0.00 sec)
 

列舉型別資料小結:
列舉型別欄位定義必須為確定的值,不能為變數、函式、表示式等;
若是向列舉型別欄位插入NULL值,且列舉型別的欄位定義為非NULL,SQL語句會執行失敗;
若是向列舉型別欄位插入,其列舉列表值域中不存在的值,則會發生欄位值的截斷,並且用空格字串值替代,其儲存的序列編號為0;
若是列舉型別欄位定義的列舉列表值域中存在空字串值,該列舉型別欄位發生欄位值截斷,則是會用空格值替代,但是其儲存的序列號與列舉列表中儲存的序列號不同,也即參考事例所示:
 

複製程式碼程式碼示例:
root@localhost : test 04:37:32> SELECT * FROM Mysqlops_enum WHERE Job_type=0;
 
+----+----------+-----------+
 
| ID | Job_type | Work_City |
 
+----+----------+-----------+
 
|  8 |          | hangzhou  |
 
+----+----------+-----------+
 
1 row in set (0.00 sec)
 
root@localhost : test 04:37:35> SELECT * FROM Mysqlops_enum WHERE Job_type='';
 
+----+----------+-----------+
 
| ID | Job_type | Work_City |
 
+----+----------+-----------+
 
|  4 |          | hangzhou  |
 
|  8 |          | hangzhou  |
 
+----+----------+-----------+
 
2 rows in set (0.00 sec)
 

若是列舉型別欄位定義為非NULL,且沒有為該欄位指定值的方式插入資料行,則把欄位定義顯式申明的預設值作為欄位預設值,沒有顯式申明則把列舉列值域表中第一個值作為預設值;
若是列舉型別欄位允許插入NULL值,則NULL值對應儲存的序列號為NULL;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29096438/viewspace-1458555/,如需轉載,請註明出處,否則將追究法律責任。

相關文章