關於MySQL varchar類型最大值,原來一直都理解錯了

寫在前面

關於MySQL varchar字段類型的最大值計算,也許咱們一直都理解錯誤了,本文從問題出發,經實踐驗證得出一些實用經驗,但願對你們的開發工做有些幫助~mysql

背景描述

最近同事在作技術方案設計時候,考慮到一個表設計時但願利用varchar類型進行存儲,而不是採用text,那就須要肯定下varchar容許的最大長度是多少,用來評估下後期是否會遇到存儲長度瓶頸。sql

那問題來了:MySQL 數據庫的varchar字段類型最大存儲長度究竟是多少?數據庫

問題分析

一切以官方文檔爲準,翻了下官方描述以下:緩存

In MySQL 4.1 the length is always 1 byte. In MySQL 5.0 the length may be either 1 byte (for up to 255) or 2 bytes (for 256 to 65535).微信

大概意思就是說:架構

  • 在MySQL 4.1之前,長度老是1個字節(varchar(20),指的是20字節分佈式

  • 在MySQL 5.0之後,長度能夠是1字節(最多255個字節)或2個字節(256到65535)編碼

按照官網說法最大值是65535bytes,utf8mb4編碼狀況下每一個字符佔4個bytes,最大值應該爲16383.75spa

65535/4=16383.75

實踐驗證

到此貌似已經有告終論了,但實際狀況真的是這樣的麼?.net

咱們來實驗下試試看?

mysql 版本:select version(); // 5.7

一、若一個表只有一個varchar類型

定義以下:

CREATETABLE`t1` (    `c`varchar(N) DEFAULTNULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

那表 t1 的`c`字段的最大長度N爲多少呢?

(65535−1−2)/4=16383

備註:
· 減1的緣由是實際行存儲從第二個字節開始;
· 減2的緣由是varchar頭部的2個字節表示長度;
· 除4的緣由是字符編碼是utf8mb4。

2)若表中包含其餘多種類型的狀況呢

定義以下:


CREATETABLE`t2` ( `c1`int(10) DEFAULTNULL, `c2`char(32) DEFAULTNULL, `c3`varchar(N) DEFAULTNULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

那表 t2 的`c`字段的最大長度N爲多少呢?

(65535−1−2−4−32*4)/4=16350

備註:
· 減一、減2的緣由同上;
· 減4的緣由是int類型佔用4個字節;
· 減32*4的緣由是utf8mb4編碼的char類型佔用4個字節(長度32)

咱們來驗證一下是否如上述推斷計算所述:

1)修改t2表c3字段長度爲16350

alter table `t2` modify column `c3` varchar(16350)

執行成功。

2)修改t2表c3字段長度爲16351

alter table `t2` modify column `c3` varchar(16351);

執行失敗,報錯信息以下:

Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs.

總結一下

Q:varchar到底能存多少個字符?

A:這與表使用的字符集相關,latin一、gbk、utf八、utf8mb4編碼存放一個字符分別須要佔一、二、三、4個字節,同時還要考慮到去除其餘字段的佔用影響。

實踐出真知,能夠簡單試一下以後再下結論。

 


往期熱文推薦:

「技術架構精進」專一架構研究,技術分享

 

Thanks for reading!

本文分享自微信公衆號 - 架構精進之路(jiagou_jingjin)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索