enum mysql byte_九、臭名昭著的 MySQL ENUM 类型 ( 上 )
MySQL 中,對于那些取值只有兩三個,或者五個以內的值,想必,大多數人使用的應該都是 ENUM 類型吧,而剩下的另一部分人,應該都是使用 TINYINT(1) 。 我,就是剩下的那部分人。
一方面我真的是太懶,雖然 MySQL 提供了豐富的數據類型,但我用到的真心不多,也就那么幾個 INT(11)、TINYINT、VARCHAR 和 TEXT。
我為什么不用 ENUM 類型?
因為我在入門的時候,就跳進了一個大窟窿,而且久久未上岸。
事情的經過是這樣的:
1、假設我們要保存的一列只有兩個值 true 和 false ,那么我們第一時間想到的,自然是使用 enum('T','F') 來表示對吧
所以,我們創建了下面這個表
CREATE TABLE `b` (
`k` ENUM('T','F') NOT NULL
);
簡單起見,我們只有一個字段
2、創建成功后,我們就會往里面插入數據,當然了,我們并不按正常套路出牌,而是使用下面的 SQL 語句
INSERT INTO `b` (`k`) VALUES ('W'), ('T'), ('F');
這條語句能執行成功嗎?
顯然,不能的
執行的結果為
ERROR 1265 (01000): Data truncated for column 'k' at row 1
這在最新的 MySQL 版本是直接報錯的,因為最新的幾個 MySQL 版本都開啟了嚴格模式。
如果關掉嚴格模式,或者使用比較古老的版本,僅僅是發出了一個警告而已
Query OK, 3 rows affected, 1 warning (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 1
我們可以使用 SHOW WARNINGS; 語句查看剛剛的警告
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'k' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.00 sec)
當然了,如果你以為數據是正確插入的,可就大錯特錯了,看看下面的語句
mysql> SELECT COUNT(DISTINCT k) FROM b;
+---------------------+
| COUNT(DISTINCT k) |
+---------------------+
| 3 |
+---------------------+
1 row in set (0.00 sec)
是不是大跌眼鏡,原則上來說,應該僅僅只有兩個不一樣的值 T 和 F ,而 W 竟然也能插入成功
對于這個問題,MySQL 官方還是作出了一點的解釋的
「如果在 ENUM 列中插入無效值(即,允許值列表中不存在的字符串),則會插入空字符串 ( '' ) 作為特殊錯誤值,這個空字符串可以通過此字符串具有數字值 0 來區分 正常 的空字符串 」
是不是很繞口,很簡單的規則,就是說如果往 enum 列中插入了無效的值,可以被插入,但插入的是一個特殊的空字符串,而該空字符串的數值是 0
所以,使用 enum 就要很小心了。
就因為這個原因,我始終沒有碰 enum ,當然了,另一個原因是如果要添加其它允許的值,則需要修改默認表結構,這,往往是得不償失的。
本章節,我們就來講講這個臭名昭著的 enum 類型。
MySQL ENUM 數據類型
1、首先,要說的是「 ENUM 類型其實是一個字符串類型 」,雖然作用很像 C 或 C++ 中的枚舉類型。
2、其次,要說明的是,ENUM 類型的值都是從 允許值列表中選擇
3、再次,允許值 列表在創建表結構時就定義好的,表創建完成后可以使用 alter 語句來修改允許值列表
ENUM 數據類型能夠帶來很多好處,比如
1、數據更緊湊。因為 ENUM 列一般都是有限的值,一般不多余 5 個這樣,這就比保存 true 或 false 節省空間多了。因為 MySQL 會在創建或者修改表結構時將 enum 允許的值自動編碼為數字,而這個數字一般的分配空間為 1~2 字節 ( byte ) ,具體取決于實現。
例如,將值為 medium 的100萬行插入表將需要 100 萬字節的存儲空間,而如果將實際字符串 medium存儲在 VARCHAR 列中則需要 600 萬字節。
2、更好的可讀性,雖然在存儲的是數字,但在輸入和輸出時使用的都是對應的允許值。
雖然 enum 有這兩個極大的好處,但也有不少的壞處,前面提到的就是其中之一
至于具體有哪些壞處,我們下一章節再來闡述吧
干貨推薦
附錄:MySQL 拾遺:系列文章
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的enum mysql byte_九、臭名昭著的 MySQL ENUM 类型 ( 上 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux native分区,怎么将硬盘
- 下一篇: zip版mysql5.6_mysql 5