char和varchar是最常用的两种数据类型。
一般认为,char是定长字符,varchar是可变长度字符。
在MySQL版本4.12以后,这种说法就不完全正确了。在4.12版之后,char(n)中的n代表的不再是字节长度,而是字符长度。在这个改变下,如果字符集选择的是多字节字符集,比如utf-8,那么char(n)则存储的数据就不是固定长度了。
例如,char(3)可以存储“abc”、“一二三”。显然,前面两个字符串的字节长度是不一样的。
所以只有当字符集选择了单字节字符集,比如latin1,char是固定长度。在使用多字节字符集时,char则被当作vachar类型。
这一问题是很多程序员容易忽略的。
另一个容易忽略的问题是varchar最大能存储多长字节。官方资料显示是65536,但是如果你定义一个varchar长度65535是会报错的。
实际测试,最大值是65532。这里又隐藏了一个问题,如果字符集是utf-8,定义varchar(65532)还是会报错的。因为varchar(n)中的n指的是字符长度。
说到utf-8,这也是一个问题。准确的说是MySQL的utf-8字符集。MySQL的utf-8字符集最大字符支持3个字节,而真正的utf-8字符集是最大4个字节。因此,存在出现存储发生错误的可能。
这个问题出现很久了,解决的方法就是别用MySQL的utf-8字符集。
不用MySQL的utf-8字符集,那么用什么呢?MySQL的utfmb4-8字符集。