本節主要內容:
MySQL數據類型之枚舉類型ENUM
MySQL數據庫提供針對字符串存儲的一種特殊數據類型:枚舉類型ENUM,這種數據類型可以給予我們更多提高性能、降低存儲容量和降低程序代碼理解的技巧,前面介紹了首先介紹了四種數據類型的特性總結,其后又分別介紹了布爾類型BOOL或稱布爾類型BOOLEAN,以及后續會再單獨介紹集合類型SET。
本文詳細介紹集合類型enum測試過程與總結,加深對mysql數據庫集合類型enum的理解記憶。
n? 枚舉類型ENUM
a).數據庫表mysqlops_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;