MySQL常見誤區

從業這些年,帶過不少人、也接觸過很多同事同行,發現新人甚至工作很多年的同事,對MySQL的部分原理都有相似的錯誤理解。

本文會持續整理出一些常見誤區,希望能對大家的工作學習有幫助。

MySQL版本:5.6/5.7/8.x

類型選擇和字段設計

INT長度並不能指定

常見的int(4)並不是指最大存儲9999,而是低於4位的數字會使用空格或0在左側補齊到4位。這個4是顯示寬度。
int實際上是定長字段,佔用4字節。取值範圍固定是-(231-1) ~ (231-1) ,無符號時爲0 ~ (232-1)。

延伸閱讀:

VARCHAR存儲的是字符而不是字節,但最大長度是另外的算法

VARCHAR聲明的是字符數,但存儲的是字節。

理論上最大長度是65535 bytes,但實際上往往達不到。因爲有幾個因素:

  • 65535是單行數據的最大值,實際上除了varchar,表裏應該還會有其他字段

  • varchar存放的字符串,往往會有多字節字符、一個字符佔多個字節,而我們前端展現計算長度往往用的是字符數,所以也肯定達不到65535

  • varchar字段有長度標識位,可能佔用1~2個字節,與我們聲明的字段長度、字符集單字符最大長度有關,換算關係比較複雜,一句話說不清楚。

延伸閱讀:

自增不一定連續,還可能重複

首先傳遞一個邏輯,MySQL InnoDB的自增,是使用了一個表級的計數器。

自增不一定連續:如果insert或update指定了比當前最大值更大的值,計數器會直接增加到新的最大值;如果delete已有的一行數據,計數器並不會減小。

自增可能重複:上面提到的計數器,是維護在內存中的,MySQL一旦重啓、又沒有手工重新裝載過計數器,新插入記錄自增主鍵就會重新從最小值開始,就會出現重複。

延伸閱讀:《MySQL自增列AUTO_INCREMENT詳解》

TIMESTAMP只能表達68年

TIMESTAMP以4字節整數(可看做SIGNED INT)存儲從1970-01-01T00:00:00Z(UNIX紀元)經過的秒數。UNIX紀元看做0值,小於紀元的時間插入會報錯。

有符號4字節可以表達最大絕對值爲2^31-1的數字,所以TIMESTAMP的只能表達1970-01-01T00:00:01Z ~ 2038-01-19T03:14:07Z的範圍。

延伸閱讀:《MySQL時間類型的取值範圍和存儲原理》《UNIX紀元與2038問題》

函數使用

count(column)不會統計所有行

count(column)會忽略掉值爲NULL的行,相比於count(*)count(1),統計出來的數字可能會小一些。從性能角度也不建議使用列。

更多NULL運算介紹和樣例可參考《NULL如何參與運算和統計》


以上。感謝您的閱讀。

持續更新中:

  • 更多已知的MySQL誤區
    • 字符集問題
    • 不走索引(掃描比)
    • 掃描導致的更新慢
    • 等等
  • 讀者反饋問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章