成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL插入數據會失???為什么?

數據庫 MySQL
mysql默認的utf8字符集,其實只是utf8mb3,并不完整,當插入emoji表情等特殊字符時,會報錯,導致插入、更新數據失敗。改成utf8mb4就好了,它能支持更多字符。

那天,我還在外面吃成都六姐的冒菜。

牛肉丸裹上麻醬后,狠狠嘬一口,都要入嘴了。

產品經理突然發來消息。

"線上有些用戶不能注冊了"。

心想著"關我x事,又不是我做的模塊",放下手機。

不對,那老哥上禮拜剛離職了,想到這里,夾住毛肚的手微微顫抖。

對面繼續發:"還有些用戶不能改名"。

"如果用上表情符號的話,問題必現"。

可以了,這下問題幾乎直接定位了。

危,速歸。

有經驗的兄弟們很容易看出,這肯定是因為字符集的緣故。

復現問題

我們來簡單復現下這個問題。

如果你有一張數據庫表,建表sql就像下面一樣。

建表sql語句

接下來如果你插入的數據是。

insert成功case

能成功。一切正常。

但如果你插入的是

insert失敗case

就會報錯。

Incorrect string value: '\xF0\x9F\x98\x81' for column 'name' at row 1

區別在于后者多了個emoji表情。

明明也是字符串,為什么字符串里含有emoji表情,插入就會報錯呢?

我們從字符集編碼這個話題開始聊起。

編碼和字符集的關系

雖然我們平時可以在編輯器上輸入各種中文英文字母,但這些都是給人讀的,不是給計算機讀的,其實計算機真正保存和傳輸數據都是以二進制0101的格式進行的。

那么就需要有一個規則,把中文和英文字母轉化為二進制,比如"debug",計算機就需要把它轉化為下圖這樣。

debug的編碼

其中d對應十六進制下的64,它可以轉換為01二進制的格式。

于是字母和數字就這樣一一對應起來了,這就是ASCII編碼格式。

它用一個字節,也就是8位來標識字符,基礎符號有128個,擴展符號也是128個。

也就只能表示下英文字母和數字。

這哪里夠用。

塞牙縫都不夠。

于是為了標識中文,出現了GB2312的編碼格式。為了標識希臘語,出現了greek編碼格式,為了標識俄語,整了cp866編碼格式。

這百花齊放的場面,顯然不是一個愛寫if else的程序員想看到的。

為了統一它們,于是出現了Unicode編碼格式,它用了2~4個字節來表示字符,這樣理論上所有符號都能被收錄進去,并且它還完全兼容ASCII的編碼,也就是說,同樣是字母d,在ASCII用64表示,在Unicode里還是用64來表示。

但不同的地方是ASCII編碼用1個字節來表示,而Unicode用則兩個字節來表示。

比如下圖,同樣都是字母d,unicode比ascii多使用了一個字節。

unicode比ascii多使用一個字節

我們可以注意到,上面的unicode編碼,放在前面的都是0,其實用不上,但還占了個字節,有點浪費,完全能隱藏掉。如果我們能做到該隱藏時隱藏,這樣就能省下不少空間,按這個思路,就是就有了UTF-8編碼。

編碼格式

來總結下。

按照一定規則把符號和二進制碼對應起來,這就是編碼。而把n多這種已經編碼的字符聚在一起,就是我們常說的字符集。

比如utf-8字符集就是所有utf-8編碼格式的字符的合集。

字符和字符集的關系

mysql的字符集

想看下mysql支持哪些字符集??梢詧绦?show charset。

數據庫支持哪些字符集

上面這么多字符集,我們只需要關注utf8和utf8mb4就夠了。

utf8和utf8mb4的區別

上面提到utf-8是在unicode的基礎上做的優化,既然unicode有辦法表示所有字符,那utf-8也一樣可以表示所有字符,為了避免混淆,我在后面叫它大utf8。

而從上面mysql支持的字符集的圖里,我們看到了utf8和utf8mb4。

先說utf8mb4編碼,mb4就是most bytes 4的意思,從上圖最右邊的Maxlen可以看到,它最大支持用4個字節來表示字符,它幾乎可以用來表示目前已知的所有的字符。

再說mysql字符集里的utf8,它是數據庫的默認字符集。但注意,此utf8非彼utf8,我們叫它小utf8字符集。為什么這么說,因為從Maxlen可以看出,它最多支持用3個字節去表示字符,按utf8mb4的命名方式,準確點應該叫它utf8mb3。

不好意思,有被嚴謹到的兄弟們,評論區扣個"嚴謹"。

它就像是閹割版的utf8mb4,只支持部分字符。比如emoji表情,它就不支持。

utf8mb3和utf8mb4的關系

而mysql支持的字符集里,第三列,collation,它是指字符集的比較規則。

比如,"debug"和"Debug"是同一個單詞,但它們大小寫不同,該不該判為同一個單詞呢。

這時候就需要用到collation了。

通過SHOW COLLATION WHERE Charset = 'utf8mb4';可以查看到utf8mb4下支持什么比較規則。

utf8mb4字符集比較規則

如果collation = utf8mb4_general_ci,是指使用utf8mb4字符集的前提下,挨個字符進行比較(general),并且不區分大小寫(_ci,case insensitice)。

這種情況下,"debug"和"Debug"是同一個單詞。

對比規則-大小寫不敏感

如果改成collation=utf8mb4_bin,就是指挨個比較二進制位大小。

于是"debug"和"Debug"就不是同一個單詞。

對比規則-大小寫敏感

那utf8mb4對比utf8mb3有什么劣勢嗎?

我們知道數據庫表里,字段類型如果是char(2)的話,里面的2是指字符個數,也就是說不管這張表用的是什么編碼的字符集,都能放上2個字符。

而char又是固定長度,為了能放下2個utf8mb4的字符,char會默認保留2*4(maxlen=4)= 8個字節的空間。

如果是utf8mb3,則會默認保留 2 * 3 (maxlen=3) = 6個字節的空間。也就是說,在這種情況下,utf8mb4會比utf8mb3多使用一些空間。

但這真的無關緊要,如果我不用char,用varchar就好了,varchar不是固定長度,也就沒有上面這些麻煩事了。

所以我個人認為,utf8mb4比起 utf8mb3 幾乎沒有劣勢。

如何查看數據庫表的字符集

如果我們不知道自己的表是用的哪種字符集,可以通過下面的方式進行查看。

查看數據庫表的字符集

再看報錯原因

到這里,我們回到文章開頭的問題。

因為數據庫表在建表的時候使用 DEFAULT CHARSET=utf8, 相當于指定了utf8mb3字符集格式。

而在執行insert數據的時候,又不講武德,加入了emoji表情這種utf8mb4才能支持的字符,mysql識別到這是utf8mb3不支持的字符,于是忍痛報錯。

要修復也很簡單,執行下面的sql語句,就可以把數據庫表的字符集改成utf8mb4。

ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

答應我,以后建表,我們都無腦選utf8mb4。

選utf8除了在char字段場景下會比utf8mb4稍微省一點空間外,幾乎沒任何好處。

這點空間省下來了能提高你的績效嗎?不能。

但如果因此炸雷了,那你號就沒了。

總結

  • ASCII編碼支持數字和字母。大佬們為了支持中文引入了GB2312編碼格式,其他國家的大佬們為了支持更多語言和符號,也引入了相應的編碼格式。為了統一這些各種編碼格式,大佬們又引入了unicode編碼格式,而utf-8則在unicode的基礎上做了優化,壓縮了空間。
  • mysql默認的utf8字符集,其實只是utf8mb3,并不完整,當插入emoji表情等特殊字符時,會報錯,導致插入、更新數據失敗。改成utf8mb4就好了,它能支持更多字符。
  • mysql建表時如果不知道該選什么字符集,無腦選utf8mb4就行了,你會感謝我的。

最后

原本A同學設計這張表的時候非常簡單,也有字符串類型的字段,但字段含義決定了肯定不會有奇奇怪怪的字符,用utf8很合理,還省空間。

后來交接給了B同學,B同學在這基礎上加過非常多的字段,離職前最后一個需求加的這個名稱字段,所幸并沒炸雷。最后到了我這里。

好一個擊鼓傳雷。

有點東西哦。

那么問題來了。

這樣的一個事故,復盤會一開,會掛P幾呢?

責任編輯:姜華 來源: 小白debug
相關推薦

2012-05-02 10:08:51

桌面Linux微軟

2023-03-22 09:10:18

IT文檔語言

2024-07-16 08:03:43

2023-05-06 11:05:12

2011-07-01 09:13:51

軟件測試項目

2018-05-09 09:55:36

數據分析

2021-05-10 09:35:58

Kubernetes節點Join

2021-03-08 11:11:00

機器學習人工智能AI

2020-02-17 09:14:16

云計算云遷移公共云

2013-03-06 16:56:47

2020-03-27 16:05:49

數據庫數據MySQL

2012-06-17 13:14:29

創業創業公司信息圖

2018-05-07 15:30:13

數據治理分析數據集

2018-05-07 10:32:40

數據分析

2017-08-08 16:38:50

IT敏捷devops

2023-10-30 07:24:18

IT項目DevOps

2019-12-16 15:17:13

大數據信息安全數據庫

2010-06-11 17:13:34

MySQL表索引

2024-12-16 09:11:57

2018-03-23 08:31:36

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美高清视频一区 | 成人av在线大片 | 亚洲综合无码一区二区 | 亚洲欧美一区二区三区在线 | 日韩欧美中文 | 亚洲不卡在线视频 | 欧美天堂在线 | 三级高清| 欧美中国少妇xxx性高请视频 | 91原创视频在线观看 | 亚洲精品视频在线 | 国产精品一区二区不卡 | 午夜视频在线观看一区二区 | 亚洲网址在线观看 | 成人在线精品视频 | 中文字幕动漫成人 | 特级丰满少妇一级aaaa爱毛片 | 一级欧美| 欧洲性生活视频 | 91精品久久久| 亚洲品质自拍视频 | 色偷偷人人澡人人爽人人模 | 色综合久久天天综合网 | 麻豆精品久久久 | 亚洲一区二区三区在线视频 | 欧美精品在线视频 | 97超在线视频 | 日韩欧美在线免费 | 免费精品一区 | 国产在线精品区 | 91在线观看视频 | 久久久久国产一区二区三区 | 亚洲综合色站 | 日韩欧美在线播放 | 亚洲综合免费 | 四虎影视免费在线 | 亚洲久在线| 国产乱码久久久久久 | 国产在线精品一区二区三区 | 九九热免费视频在线观看 | 国产精品高潮呻吟 |