自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

賜我白日夢發表於2021-03-14

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

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

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

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

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

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

公眾號後臺回覆:資料庫 可以參與抽獎活動,3本《MySQL技術內幕-InnoDB儲存引擎》

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

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

Hi同學,聽說你上一面表現的還可以,這一面要不我們繼續?自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?


嗯,好啊!自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

好,說說你瞭解的char和varchar兩種資料型別的區別吧自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?,char和varchar是MySQL中提供的兩種相似的列,都能儲存字元或者儲存字串。


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


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

嗯,那它倆有啥區別?自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?


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


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

嗯,那你說說char型別怎麼個長度不可變法呢?自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?


舉例說: 

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


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


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

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


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

嗯,你上面的回答總體上是沒有問題的。自導自演的面試現場:說說char 和 varchar的區別你瞭解多少? 不過我還有幾個問題,想問你一下。假如我的建表語句是這樣的:


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都能執行成功。


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

嗯,是的自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?。大家都在說varchar儲存可變長度的字串、char用來儲存不可變長度的字串。其實當使用的字符集編碼不同時,char能儲存的位元組數是會變化的!


自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

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


建立表:

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表示開啟了嚴格模式

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?



上面的insert sql就會報錯

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?


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

自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?



自導自演的面試現場:說說char 和 varchar的區別你瞭解多少?

白日夢補充:
點選瞭解之前的筆記: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專題,公眾號首發!持續更新中~

相關文章