MySql中varchar长度设置解疑
根据⾃⼰多年的⼯作经验,特别是在接收旧的项⽬时,varchar的长度设置有不同的风格,针对varchar长度的设置问题,⾃⼰划分了不同的门派。
1.强迫症派:长度设置为4或者8的倍数,达到内存对齐的⽬的;
2.贴⼼派:长度设置成(2^n)-1;
3.务实派:需要多长就设置多长,不关⼼2的⼏次幂;
4.逍遥派:varchar是存储可变长字符串的,n值尽可能设置的⼤,⽐如varchar(1000)。
下⾯分析那种⽅案更合理:
1.varchar(n)的最⼤值字符数是多少
varchar的最⼤可以保存65535字节,但是具体保存多少个字符,不同的编码不⼀样。
MySql 5.0 之前的版本: n指的是n个字节varchar2最大长度
n的最⼤值是65535,如果存放utf-8格式只能保存 (n / 3)个汉字,即如果varchar(20) 那么只能保存6个汉字;
MySql 5.0 之后的版本: n指的是n个字符
如果存放utf-8格式,那么⽆论是数字,字母还是汉字,都可存放n个,即如果varchar(20) 那么可以保存20个汉字(⾃⼰亲测可以); varchar到底能存多少个字符?这与使⽤的字符集相关,
latin1类型: varchar(n)中每个字符最多占1个字节,最⼤长度不能超过(65535 / 1);
gbk类型:varchar(n)中每个字符最多占2个字节,最⼤长度不能超过(65535 / 2);
utf-8类型:varchar(n)中每个字符最多占3个字节,最⼤长度不能超过(65535 / 3)。
关于这个长度的计算, 有篇⽂章讲的很通透, 实际操作了下,计算很准确的, 详情链接:
有兴趣的同学可以了解下!
如果读起来没有啥概念, 我⼤致描述下, ⼀张表, 最多可以有85个varchar(255) default null字段 + 1个varchar(109) default null
2.varchar(n)需要1到2个额外字节记录长度n的值
当n<=255的时候,只需要1个字节记录即可(数据表⽰范围:0 ~ (2^8-1),即0~255);当n>255的时候,则需要2个字节存储n的值((2^8)~ (2^16)-1,即256~65535)。
varchar字段报错的实际值得长度保存在第⼀个或者前两个字节中。
所以:
a.如果varchar(20),实际是需要1+20个字节的存储空间;
b.如果varchar(255),实际是需要1+255个字节的存储空间;
c.如果varchar(256),实际是需要2+256个字节的存储空间;
d.如果varchar(500),实际是需要2+500个字节的存储空间.
因此 强迫症派的n=4或者8的倍数达到内存对齐的⽬的是不成⽴的,如果要达到内存对齐,varchar长度应该为(2^n)-1才能够达到,所
以强迫症派的⽅法不可取。
3.varchar的内存对齐的问题
因为varchar是存储可变长字符串,
因此:
a.如果name varchar(8),那么name='12345678',实际长度为1+8;
b.如果name varchar(32),那么name='12345678',实际长度为1+8;
c.如果name varchar(16),那么name='1234',实际长度为1+4;
贴⼼派的varchar长度应该为(2^n)-1是不能够达到内存对齐的⽬的的,长度是以实际保存的字符串长度为准的,因此贴⼼派也是不准确的。
另外,InnoDB是以页(page)为基本的存储单位,⼀个页会有⼀⾏或者多⾏(row)数据,数据的读取是基于page的,不是按照row读取的,因此也就没有内存对齐的问题了。
4.n值尽可能设置的⼤的问题
逍遥派的结论⼀看就不靠谱,但是还是需要理论进⾏驳斥的。
在MySql在查询是需要创建临时表的时候(union,order by、group by,⼦查询),在MySql读取数据之前,是只知道varchar的长度n,不知道实际数据的长度的,但是读取数据之前需要预分配内存空间,MySql是根据varchar(n)中的n来进⾏分配内存的,这样也是最合理的⽅式,不可能分配⼩于n个字符的空间,因此针对逍遥派的varchar(1000)设置就会预先分配1000个字符空间,很显然这个是⼗分不靠谱的设计。
结论:
varchar需要多长就设置多长,不必考虑那么复杂, 根据业务需要,来设置即可, 通常建议<=255 .
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论