­

面試現場:說說char 和 varchar的區別你了解多少?

Hi,大家好!我是白日夢!本文是MySQL專題的第 26 篇。

下文還是白日夢以自導自演的方式,圍繞「說說char 和 varchar的區別你了解多少?」展開本話題。看看你能抗到第幾問吧

換一種寫作風格,自導自演面試現場!感覺這樣還是比較有趣的,歡迎大家訂閱我的MySQL專題,公眾號首發!持續更新中~

點擊閱讀原文,格式會好看一點哦~

點擊閱讀原文,格式會好看一點哦~

點擊閱讀原文,格式會好看一點哦~

歡迎關注白日夢,公眾號首發!持續連載中




Hi同學,聽說你上一面表現的還可以,這一面要不咱繼續?



嗯,好啊!









好,說說你了解的char和varchar兩種數據類型的區別吧



,char和varchar是MySQL中提供的兩種相似的列,都能存儲字元或者存儲字元串。


比如類型為char(5)的列可以存儲5個字元、類型為varchar(5)的列也能存儲5個字元。









嗯,那它倆有啥區別?



嗯,它們確實存在區別。對於char類型來說,它的存儲的列的長度是不可變的。而varchar類型的列可以存儲可變長度的字元串。









嗯,那你說說char類型怎麼個長度不可變法呢?



舉例說: 

插入時:比如char(5)的列表示這個列佔用的存儲空間一直是5個字元大小。你可以往類型為char(5)的a列中插入”abc”,那”abc”很顯然是3個字元,而不是5個字元,此時在MySQL底層會替你將”abc”後面追加兩個空格字元成為:”abc  “


檢索時:當你往外檢索上面提到的a列時,MySQL會自動幫你做一次trim() 操作,幫你去掉最後的空格,返回”abc”。






實戰體會一下:插入時MySQL替我們添加空格,檢索時替我們去掉空格的例子。










嗯,你上面的回答總體上是沒有問題的。 不過我還有幾個問題,想問你一下。假如我的建表語句是這樣的:


create table t3(a char(5)) charset= utf8 engine = innoDB;


你注意:表的字符集類型是:GBK,那我的問題是:你覺得下面的兩條sql能執行成功嘛?又為什麼呢?


insert into t select '12345'; insert into t select '賜我白日夢';



嗯,兩條SQL都能執行成功的!創建數據表時你指定了char(5),它的意思是這列可以存儲5個字元而不是5個位元組


對數字來說它是被包含在utf8中的,並且每個數字只會佔用一個byte,而中文也會被包含utf8中的,每個中文佔用3個byte。


綜上:當charset為utf8時,char(5) 這一列可以存儲的位元組範圍是[5*1,5*3],也就是[5,15]。所以上面的兩個SQL都能執行成功。









嗯,是的。大家都在說varchar存儲可變長度的字元串、char用來存儲不可變長度的字元串。其實當使用的字符集編碼不同時,char能存儲的位元組數是會變化的!






那你在看下面的這個例子:


創建表:

create table t(a varchar(2)) charset=utf8 engine = innoDB;

插入數據:

insert into t4 select 'abcd';


你注意,a列為varchar類型,且的長度為2。

你絕對上面的insert sql會執行成功嘛?會不會出現”abcd”被截斷成”ab”,然後僅僅將”ab”存儲進資料庫的情況?



嗯,很明顯varchar的期望長度是2,但是你插入的字元串長度為4。這時sql是否能執行成功取決你 sql mode。


當sql mode為嚴格(strict)模式時。下圖中的sql_mode中的 strict_trans_tables表示開啟了嚴格模式



上面的insert sql就會報錯


當sql mode設置為非嚴格,再重試會發現:MySQL將超出2字元以外的字元砍掉了。保留下”ab”,然後保存進資料庫中







白日夢補充:
點擊了解之前的筆記:sql_mode與日期類型的愛恨情仇?

推薦閱讀

  1. MySQL的修仙之路,圖文談談如何學MySQL、如何進階!(已發布)
  2. 面前突擊!33道資料庫高頻面試題,你值得擁有!(已發布)
  3. 大家常說的基數是什麼?(已發布)
  4. 講講什麼是慢查!如何監控?如何排查?(已發布)
  5. 對NotNull欄位插入Null值有啥現象?(已發布)
  6. 能談談 date、datetime、time、timestamp、year的區別嗎?(已發布)
  7. 了解資料庫的查詢快取和BufferPool嗎?談談看!(已發布)
  8. 你知道資料庫緩衝池中的LRU-List嗎?(已發布)
  9. 談談資料庫緩衝池中的Free-List?(已發布)
  10. 談談資料庫緩衝池中的Flush-List?(已發布)
  11. 了解臟頁刷回磁碟的時機嗎?(已發布)
  12. 用十一張圖講清楚,當你CRUD時BufferPool中發生了什麼!以及BufferPool的優化!(已發布)
  13. 聽說過表空間沒?什麼是表空間?什麼是數據表?(已發布)
  14. 談談MySQL的:數據區、數據段、數據頁、數據頁究竟長什麼樣?了解數據頁分裂嗎?談談看!(已發布)
  15. 談談MySQL的行記錄是什麼?長啥樣?(已發布)
  16. 了解MySQL的行溢出機制嗎?(已發布)
  17. 說說fsync這個系統調用吧! (已發布)
  18. 簡述undo log、truncate、以及undo log如何幫你回滾事物! (已發布)
  19. 我勸!這位年輕人不講MVCC,耗子尾汁! (已發布)
  20. MySQL的崩潰恢復到底是怎麼回事? (已發布)
  21. MySQL的binlog有啥用?誰寫的?在哪裡?怎麼配置 (已發布)
  22. MySQL的bin log的寫入機制 (已發布)
  23. 刪庫後!除了跑路還能幹什麼?(已發布)
  24. 自導自演的面試現場,趣學資料庫的10種文件(已發布)
  25. 大型面試現場:一條update sql執行都經歷什麼?(已發布)
  26. 大型翻車現場:如何實現記錄存在的話就更新,如果記錄不存在的話就插入。(已發布)

最後,歡迎關注白日夢的公號哦~

換一種寫作風格,自導自演面試現場!感覺這樣還是比較有趣的,歡迎大家訂閱我的MySQL專題,公眾號首發!持續更新中~

Tags: