https://blog.csdn.net/qq_43544492/article/details/108188994
https://www.cnblogs.com/Lance–blog/p/5193027.html
1.mysql中char与varchar的区别
- char:定长,效率高,一般用于固定长度的表单提交数据存储;例如:身份证号,手机号,电话,密码等;
- varchar:不定长,效率偏低
2.varchar类型的变化
- MySQL 数据库的varchar类型在4.1以下的版本中的最大长度限制为255,其数据范围可以是0-255或者1~255(根据不同版本数据库来定)。
- varchar在MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放65532个字节的数据,起始位和结束位占去了3个字节。
- MySQL 数据库的varchar类型在4.1以下的版本中,nvarchar(存储的是Unicode数据类型的字符)不管是一个字符还是一个汉字,都存为2个字 节 ,一般用作中文或者其他语言输入,这样不容易乱码 ;varchar: 汉字是2个字节,其他字符存为1个字节 ,varchar适合输入英文和数字
- 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) ;5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是 65532字节 ;varchar(20)在Mysql4中最大也不过是20个字节,但是Mysql5根据编码不同,存储大小也不同,具体有以下规则:
a) 存储限制
varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节),因此最大长度不能超过65535。
b) 编码长度限制
- 字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;
- 字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。
- 若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
c) 行长度限制
导致实际应用中varchar长度限制的是一个行定义的长度。 MySQL要求一个行的定义长度不能超过65535(字节)。若定义的表长度超过这个值,则提示
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs。
3.CHAR(M),VARCHAR(M)不同之处
- CHAR(M)定义的列的长度为固定的,M取值可以为0~255之间,当保存CHAR值时,在它们的右边填充空格(0x20)以达到指定的长度。
- 当检索到CHAR值时,尾部的空格被删除掉。在存储或检索过程中不进行大小写转换。
- CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义 char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充。
- VARCHAR(M)定义的列的长度为可变长字符串,M取值可以为0~65535之间,(VARCHAR的最大有效长度由最大行大小和使用 的字符集确定。整体最大长度是65,532字节)
- VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则 使用两个字节)。
- VARCHAR值保存时不进行填充。当值保存和检索时尾部的空格仍保留,varchar存储变长数据,但存储效率没有 CHAR高
行为 | char字段 | varchar字段 |
---|---|---|
最大长度 | 255字符 | 65535个字节(实际测试为65532字节),varchar(N),中的N为字符数,所以括号中最大的字符数还得通过编码来算。注意:一张表中所有varchar类型的最大长度之和不能超过65532字节 |
是否定长 | 定长。对于compact行记录格式,不足使用0x20(空格)填充,如果该字段为NULL,则不占空间。而对于redundant行记录格式,不足使用0x00填充,如果该字段为NULL,仍然占空间 | 不定长。无论是compact或者Redundant行记录格式,都不占空间。存在行溢出的情况,溢出数据存放在Uncompressed BLOB Page 中 |
空间使用 | 会有浪费 | 更加节省 |
查找效率 | 高 | 低 |
尾部空格 | 插入时不会省略,查找时省略 | 插入时省略 |
like查找 | 语句中like后的’ '不会省 | 语句中like后的’ '不会省,字段结尾的空格也不会省 |
- 如果分配给CHAR或VARCHAR列的值超过列的最大长度,则对值进行裁剪以使其适合。如果被裁掉的字符不是空格,则会产生一条警告。如果裁剪非空格字符,则会造成错误(而不是警告)并通过使用严格SQL模式禁用值的插入
使用场景
- 根据字符的长度来判断。如某个字段,像人的名字,其最长的长度也是有限的。如我们给其分配18个字符长度即可。
- 考虑其长度的是否相近。如果某个字段其长度虽然比较长,但是其长度总是近似的,如一般在90个到100个字符之间,甚至是相同的长度。此时比较适合采用CHAR字符类型。比较典型的应用就是MD5哈希值。
- 十分频繁改变的column使用char
- 从碎片角度进行考虑。使用CHAR字符型时,由于存储空间都是一次性分配的
- 即使使用Varchar数据类型,也不能够太过于慷慨
总结
- char(n)中的n是字符数,范围是0~255(总的字节不超过n * 字符编码)(额外需要1到2个字节来存长度)
- varchar(n)中的n也是字符数,但是最大值需要通过编码来算,不能超过65535字节(从中还需要拿出1到2个字节来存长度)
- 一般定长的数据选用char类型,比如身份证号,手机号,电话等,长度变化很大的可以使用varchar类型
- 注意尾部空格的匹配,特别是插入时和使用like查找时