標籤:mysql字元集研究
通過官方文檔可知一行最多存65535個位元組。 utf-8 字元測試1 建表 一個漢字在utf-8中佔3個位元組
通過計算65535/3 可以得出每行最多存21845,建表
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E6%9C%80%E5%A4%A7%E5%AD%97%E7%AC%A6%E5%A4%B1%E8%B4%A5.jpg?version=1&modificationDate=1432004499000&api=v2" alt="%E6%9C%80%E5%A4%A7%E5%AD%97%E7%AC%A6%E5%" />
建立失敗 原因是varchar(N)的前兩個字元是表是varchar的長度。字元為空白時儲存是從第二位是從第2位開始,也就是N=(65535-2-1)/3 =21845
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E6%9C%80%E5%A4%A7%E5%AD%97%E7%AC%A6-1.jpg?version=1&modificationDate=1432004695000&api=v2" alt="%E6%9C%80%E5%A4%A7%E5%AD%97%E7%AC%A6-1.j" />
2 插入資料比較表的位元組變化
查看空表所佔位元組 空表所佔位元組 16384
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E7%A9%BA%E8%A1%A8.jpg?version=1&modificationDate=1432004876000&api=v2" alt="%E7%A9%BA%E8%A1%A8.jpg?version=1&modific" />
插入資料
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E6%8F%92%E5%85%A5.jpg?version=2&modificationDate=1432022834000&api=v2" alt="%E6%8F%92%E5%85%A5.jpg?version=2&modific" />
查看錶的變化並計算 (備忘這是測試中插入兩行後的要除2)
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E8%8C%B6%E5%90%8E.jpg?version=1&modificationDate=1432005228000&api=v2" alt="%E8%8C%B6%E5%90%8E.jpg?version=1&modific" />
計算表的大小147456/2-16384-1=65535 (1 是表中標註1行佔用的位元組)
字元數查看 select char_length(a1),length(a1) from tb_utf8;
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E5%AD%97%E7%AC%A6%E6%95%B0.jpg?version=1&modificationDate=1432005676000&api=v2" alt="%E5%AD%97%E7%AC%A6%E6%95%B0.jpg?version=" />
驗證驗證為空白和不為空白時字元佔用
varchar (21844) 後正好佔用65533個位元組 tinyint類型佔用一個自己 65535=65532+2+1
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E4%B8%8D%E4%B8%BA%E7%A9%BA.jpg?version=1&modificationDate=1432014634000&api=v2" alt="%E4%B8%8D%E4%B8%BA%E7%A9%BA.jpg?version=" />
varchar 為空白時驗證
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E7%A9%BA.jpg?version=1&modificationDate=1432014857000&api=v2" alt="%E7%A9%BA.jpg?version=1&modificationDate" />
可以用看出為空白需要一個位元組去標示,表不能建立
結論: varchar 在utf-8中一個漢字佔用3個位元組, 數字和字母都佔用一個位元組。 為空白需要一個位元組去標示。
gbk 字元集測試建表: 根據gbk編碼一個漢字佔用2個位元組,一行最多有65535個位元組和上邊測試的為空白時多佔一個位元組。可以計算出varchar(N) N在 varchar在為空白和非空的值
為空白 (65535-2-1)/2 = 32766個漢字 非空 (65535-2)/2=32766.5 也就是非空狀態下可以多建一個tinyint類型
varchar為空白建表
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/k.jpg?version=1&modificationDate=1432021239000&api=v2" alt="k.jpg?version=1&modificationDate=1432021" />
varchar 非空建表
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/fk.jpg?version=1&modificationDate=1432021270000&api=v2" alt="fk.jpg?version=1&modificationDate=143202" />
注釋: 在建表時如果varchar超過規定位元組數時會預設轉換字元類型
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/c.jpg?version=1&modificationDate=1432021367000&api=v2" alt="c.jpg?version=1&modificationDate=1432021" />
插入資料後查看插入資料量
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/%E6%8F%92%E5%85%A5.jpg?version=2&modificationDate=1432022834000&api=v2" alt="%E6%8F%92%E5%85%A5.jpg?version=2&modific" />
查看資料佔用的位元組
插入前表
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/q.jpg?version=1&modificationDate=1432022919000&api=v2" alt="q.jpg?version=1&modificationDate=1432022" />
插入後
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/h.jpg?version=1&modificationDate=1432022941000&api=v2" alt="h.jpg?version=1&modificationDate=1432022" />
結論: 在gbk字元中varchar(N) ,N<=23766個漢字 。如果N 大於32766 mysql 會預設的轉換字元類型。 gdk中能存32766個漢字或者數字字母。
latin1 字元集 測試
1character=1byte, 1漢字=2character,
建表 因為在latin1 中一個位元組=1個字元 ,建表時varchar(N) N 在varchar不為空白的時 N=65533 為空白時N=65532
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/1.jpg?version=1&modificationDate=1432027180000&api=v2" alt="1.jpg?version=1&modificationDate=1432027" />
分別插入字母和漢字查看插入資料結果
650) this.width=650;" class="confluence-embedded-image" src="http://wiki.op.xywy.com/download/attachments/5736618/j1.jpg?version=1&modificationDate=1432028402000&api=v2" alt="j1.jpg?version=1&modificationDate=143202" />
可以看到插入的字元和漢字情況 通過計算插入漢字65523 ,插入漢字(65523-1)/2 個漢字。
顯示漢字長度不正確原因
在插入漢字是如果漢字大於varchar(n) 中(N-1)/2 的值 ,N為 是奇數 。插入的值為:漢字個數+1Null 字元 漢字個數=(N-1)/2
結論 : latin1 中varchar(N) N 最多能插入65523 個字母或數字,能插入N/2 個漢字
mysql 字元集