一、長度標識說
char, varchar類型的值,會有一個長度標識位來存值長度。
當定義varchar長度小於等於255時,長度標識位需要一個字節;
當大於255時,長度標識位需要兩個字節
也就是說,當我們定義一個varchar(255)的字段時,其實它真實使用的空間是256(255+1)字節;(注意,字段非空,latin1編碼)
當我們定義一個一個varchar(256)字段時,它真實使用的空間是258(256+2)字節
注意,上面的例子字符集用的latin1(單字節編碼),如果使用utf8mb4,在mysql中一個長度需要四個字節,計算臨界值時需要考慮。
實測MySql 8.0 所有字段共用
utf8mb4 65535/4=16383.75 varchar()最大16381
utf8(utf8mb3) 65535/3=21845 varchar()最大21841
二、索引說
很多時候我們設置varchar(255)都習以為常了,甚至我還遇到過有人以為varchar不能設置超過255的人。其實varchar沒有明確最大長度,然后有人說那65535字節(bytes)不是嗎?
但是事實上如果你用的 utf8 編碼的話按理最大可以設置到 varchar(21845),但是其實一般都會說你超出。其實MySQL要求一個行定義長度不能超過 65535 bytes(所有字符串類型字段包括其字段名稱占用空間都計算在內, text、blob等大字段類型除外)。
如下圖我先設置了個21842成功了,后面加個長度為3的varchar都會報錯,所有如果一個表有很多varchar字段的時候,不應該把varchar設置的特別大,會影響后面的字段
言歸正傳那為什么我們會經常性設置成varchar(255)呢?
首先我們要知道一個概念:InnoDB存儲引擎的表索引的前綴長度最長是767字節(bytes)
你如果需要建索引,就不能超過 767 bytes;utf8編碼時 255*3=765bytes ,恰恰是能建索引情況下的最大值。
如果像lavavel5.3往后 使用的是utf8mb4編碼,默認字符長度則應該是 767除以4向下取整,也就是191。
總結:varchar(255) 不是最優的字符長度,最優還是應該根據實際需要的來。但是這是一個保證你能少出錯的一個很好的默認值