MySQL中enum插入的注意事項有哪些,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
創(chuàng)新互聯(lián)建站主要從事成都網(wǎng)站建設(shè)、成都做網(wǎng)站、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)梁山,十載網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
今天在執(zhí)行開發(fā)發(fā)過來的工單的時候,source批量導(dǎo)入執(zhí)行時候發(fā)現(xiàn)報了很多警告 提示 truncate for column xxxxx 。導(dǎo)入完成后,使用select查詢后,發(fā)現(xiàn)大量數(shù)據(jù)未成功插入。
后來發(fā)現(xiàn)是enum字段沒有加引號搞的鬼。
結(jié)論:
enum的字段,在插入的時候,必須帶上引號。否則會出現(xiàn)不可預(yù)期的問題。
驗證過程如下:
[none] > use test;
[test] > create table t1(
a int primary key auto_increment,
b enum('4','3','2','1') default '3');
[test] > INSERT INTO t1 (b) VALUES (4);
Query OK, 1 row affected
Time: 0.012s
[test] > INSERT INTO t1 (b) VALUES ('4');
Query OK, 1 row affected
Time: 0.012s
[test] > SELECT * from t1;
+-----+-----+
| a | b |
|-----+-----|
| 1 | 1 | ---> 這里我們執(zhí)行的是 INSERT INTO t1 (b) VALUES (4); 結(jié)果卻插入的是數(shù)值1,和我們實際上的目標(biāo)結(jié)果完全不一致。
| 2 | 4 | ---> 這里我們執(zhí)行的是 INSERT INTO t1 (b) VALUES ('4'); 這里插入帶引號的4,和我們的預(yù)期結(jié)果一致。
+-----+-----+
原因:
enum類型的字段插入數(shù)值的時候, 帶引號的時候,插入的才是真正的數(shù)值。 如果不帶引號插入的話,實際上是插入的key(如上面的例子中 INSERT INTO t1 (b) VALUES (4),插入的是b列第四個default值,也就是取enum('4','3','2','1')第四個默認(rèn)值,即最終插入的是數(shù)值1)。
試驗,寬松sql_mode下的插入情況:
[test] > set session sql_mode='';
[test] > INSERT INTO t1 (b) VALUES (5); ---> 插入一個超出enum下標(biāo)范圍的值
Query OK, 1 row affected
Time: 0.012s
[test] > INSERT INTO t1 (b) VALUES ('5'); ---> 插入一個不在enum允許的值
Query OK, 1 row affected
Time: 0.011s
[test] > SELECT * from t1;
+-----+-----+
| a | b |
|-----+-----|
| 1 | 1 |
| 2 | 4 |
| 3 | |
| 4 | |
+-----+-----+
[test] > SELECT * from t1 where b = '';
+-----+-----+
| a | b |
|-----+-----|
| 3 | |
| 4 | |
+-----+-----+
[test] > SELECT * from t1 where b is null;
+-----+-----+
| a | b |
|-----+-----|
+-----+-----+
可以看到在sql_mode為空的時候,雖然插入的時候沒有報錯,但是實際上查詢是沒有結(jié)果的,(查出來后插入的2行的b是''空值,不是NULL)。
繼續(xù)試驗,嚴(yán)格的sql_mode下異常插入的情況:
[test] > set session sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
[test] > INSERT INTO t1 (b) VALUES ('5');
(1265, u"Data truncated for column 'b' at row 1")
[test] > INSERT INTO t1 (b) VALUES (5);
(1265, u"Data truncated for column 'b' at row 1")
可以看到嚴(yán)格的sql_mode下,我們的異常插入就直接報錯了。
ENUM枚舉
一般不建議使用,后期不便于擴(kuò)展。任何不在枚舉的范圍的值插入都會報錯,一般用tinyint替代ENUM比較合適。
ENUM的字段值不區(qū)分大小寫。如insert into tb1 values("M"); 和insert into tb1 values("m");效果一樣的。
補(bǔ)充:
enum的存儲原理:
(http://justwinit.cn/post/7354/?utm_source=tuicool&utm_medium=referral)
在建立enum類型的字段時,我們會給他規(guī)定一個范圍比如 enum('a','b','c'),這時mysql內(nèi)部會建立一張hash結(jié)構(gòu)的map表,類似:0000 -> a,0001 -> b,0002 -> c。
當(dāng)我插入一條數(shù)據(jù),此字段的值位a或b或c時,他存儲在里面的不是這個字符,而是對應(yīng)他的索引,也就是那個0000或0001或0002。
同樣,enum在mysql手冊上的說明:
ENUM('value1','value2',...)
1或2個字節(jié),取決于枚舉值的個數(shù)(最多65,535個值)
除非enum的個數(shù)超過了一定數(shù)量,否則他所占的存儲空間也總是1字節(jié)。
看完上述內(nèi)容,你們掌握MySQL中enum插入的注意事項有哪些的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!