标签:
今天看了一下MySQL官方文档关于CHAR和VARCHAR的描述,记录一下。主要看的有下面三个网页:
http://dev.mysql.com/doc/refman/5.7/en/char.html
http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_pad_char_to_full_length
http://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html
CHAR和VARCHAR类型是比较类似的,但在数据存取、表示长度范围、字符串末尾的空白字符处理上是有区别的,具体如下:
1、CHAR类型的字段是定长的,在你创建表的时候这个长度就已经确定了
2、CHAR可以表示的长度范围从0~255个字符,注意这里是字符不是字节
3、当存储的字符串长度小于定义的长度时,在串的后面会补充空格
4、当我们从数据库中取数据的时候,串末尾空格会被自动去掉。这里有可能会有一个问题,如果我们的串本身后面带了空格,那么这么一存一取,串后面带的空格也被去掉了
5、如果SQL MODE设置为PAD_CHAR_TO_FULL_LENGTH,则从数据库中获取到的数据,返回给我们的串后面会跟着一堆空格,包括串后面本身的空格以及存储时MySQL添加的空格,感兴趣的同学可以通过执行SET sql_mode = ‘PAD_CHAR_TO_FULL_LENGTH‘;改变SQL MODE试试看。
6、非严谨模式下,插入字串长度超过字段定义的长度时,会截断后存储,给出告警;在严谨模式下,则会中断操作,报错。如果截断的部分是空格字符,无论是严格模式还是非严格模式,直接忽略
1、VARCHAR是变长的,存储时内容前面会有1~2字节表示长度,小于等于255个字符时,一个字节表示长度,大于255个字符时,用两个字节表示长度
2、能表示的长度范围是0~65535字符
3、但实际上VARCHAR的最大长度还受到MySQL行最大字节数以及字符编码的限制的:
A、MYSQL中行的最大字节数是65535字节,表中所有的字段共享这65536字节的空间。如果某表只有一个字段,且该列为VARCHAR(n) NOT NULL,除去2字节表示长度,保存内容的空间不能超过65533字节,如果该列为VARCHAR(n),即允许为NULL,则还需要除去1位用来标记字节是否为NULL(对于MyISAM,允许为NULL的字段,MYSQL需要额外的空间记录字段是否为NULL,每个可以为NULL的字段需要额外的1个bit,InnoDB对于是否为NULL的字段存储格式一样),所以保存内容的空间不能超过65532字节
B、对于GBK编码,一个字符需要占用2个字节,能存储的字符长度不能超过n/2,对于utf-8编码,一个字符占用3个字节,能存储的字符长度不能超过n/3。
4、非严谨模式下,插入字串长度超过字段定义的长度时,会截断后存储,给出告警;在严谨模式下,则会中断操作,报错,这一点和CHAR类型一致。不同的是如果截断的部分是空格字符,无论是严格模式还是非严格模式,CHAR类型会直接忽略,而VARCHAR类型会产生告警
5、存储时不会再末尾补充空字符
6、从数据库获取数据是,也不会截取取出的数据末尾的空字符,所以如果我们存入串末尾本身是有空字符的,获取时会依然保留
7、VARCHAR比CHAR要节省空间,但处理上不如CHAR快,毕竟获取VARCHAR时需要先找到长度,再找内容
1、每个表最多能有4096个字段,这个是MySQL的硬限制,不同的引擎,可能还有额外的限制,比如InnoDB,字段不能超过1000个
2、每一行能存储的最大字节数为65535,这里是字节不是字符,具体到不同的引擎还可能有其它额外限制。举个例子,utf-8的字符最多需要3个字节来表示,我们将字段定义成CHAR(255),则mysql需要为这个字段分配255×3=765个字节,如果表中所有字段都是CHAR(255),则表中,最多能有65535/765=85个这样的字段
3、BLOB和TEXT类型分别按1~4 加上8个字节(9~12)算。也就是一个BLOB和TEXT类型按2+8个字节算,TINYBLOB和TINYTEXT按1+8=9个字节算,MEDIUMTEXT,MEDIUMBLOB分别按3+8,LONGTEXT,LONGBLOB按照4+8个字节算,这是由于BLOB和TEXT的内容是和行分开存储的,标的字段中只记录长度和位置
4、MySQL校对规则属于PADSPACE,对CHAR、VARCHAR和TEXT值进行比较都忽略尾部空格,和服务器配置以及MySQL版本都没关系。但LIKE格式匹配时,会考虑后面的空格,使用时要注意
标签:
原文地址:http://my.oschina.net/ricky716/blog/471699