varchar2最大长度
MySQL数据类型——字符串类型(CHAR、BINARY、
BLOB、TEXT、ENUM、SET)
⼀、字符串类型概述
下图列出了MySQL⽀持的字符串数据类型
字符串可以容纳任何内容,甚⾄能容纳那些⽤于表⽰图像和声⾳的⼆进制数据。
字符串可以按照⼤⼩写进⾏⽐较。此外,还可以对字符串进⾏模式匹配。(事实上,数字类型也⽀持模式匹配,只不过字符串类型的模式匹配更为常见⼀点。)
⼆、总体介绍
字符串可以⽤于表⽰任何值;从这个意义上讲,它实际上是⼀种“范型”类型。例如,可以⽤⼆进制串类 型来存储⼆进制数据,如图像、声⾳、压缩后的gzip输出。
下图列出了MySQL的所有⽤于定义字符串值列的类型,以及最⼤⼤⼩和存储空间要求:
M:表⽰列值的最⼤长度(⼆进制串以字节为单位,⾮⼆进制串以字符为单位)
L:表⽰某个给定值的字节长度
w:表⽰列字符集⾥最"宽"字符所占的字节数
BOLB和TEXT分别有多种变体,主要区别在于容纳的字符串最⼤长度不同
对于VARBINARY和VARCHAR类型,如果列值的最⼤字节长度⼩于256,那么其长度前缀将占⽤1个字节,否则,将占⽤2个字节。
除了ENUM和SET这两种类型以外,MySQL会将其他所有字符串类型的值存储为⼀串字节;并且它还会根据所存储字符串的具体类型(⼆进制或⾮⼆进制),把这些字节解释为字节串或字符串。如果这些值的长度太长,导致⽆法存储,那么会截断它们 。(在严格模式下,只有截断后的字符为空格的情况下,才会有错误提⽰。)不过,因为各种字符串类型的⼤⼩各异 (最⼤的类型能够容纳将近4GB的数据),所以在理论上完全可以到⼀种很长的字符串类型,⽤于存储各种长数据,从⽽避免信息被截断 。(实际上,字符串类型列的最⼤有效长度,取决于MySQL的 “客户端/服务 器”通信协议所⽀持的最⼤数据包长度,其默认值为1MB。)
对于ENUM和SET类型,其列定义⾥都有⼀个合法字符串值的列表,但ENUM和SET的值在内部都被存储为数字,更多相关细节在下⾯会介绍。在未启⽤严格模式的情况下,如果把某个未出现在列表⾥的值存储到ENUM或SET类型列⾥,则会导致该值被转换为⼀个空串(' ')。在严格模式下,这会导致出现错误。
三、CHAR、VARCHAR
字符串类型CHAR和VARCHAR主要⽤于保存⾮⼆进制串,因此它们有字符集和排序规则 。
CHAR和VARCHAR之间的主要区别在于:它们的长度是固定的,还是不变的;如何对待尾部空格。
CHAR是⼀种长度固定的类型,⽽VARCHAR是⼀种长度可变的类型。
从CHAR列检索出来的值,其尾部空格会被移除。对于CHAR(M)列,如果其值的长度⼩于M个字符,那么在存⼊时会⽤空格将长度补齐到M。但是,当在检索这些值时,其尾部的空格会被移除。如果启⽤SQL的PAD_CHAR_TO_ FULL_LENGTH模式,那么在检索CHAR列值 时就可以保留尾部空格。
对于VARCHAR列,其尾部空格在存储和检索时都会被保留。
CHAR和VARCHAR这两种数据类型的选择:
如果所有值的长度都是M个字符,那 么VARCHAR(M)列会⽐CHAR(M)列多占⽤存储空间,因为前⼀种类型还需要⽤额外的字节来记录值的长度。
反之,如果数据长短不⼀,那么选⽤VARCHAR类型可以节省空格占⽤的存储空间。CHAR(M)列始终会占⽤M个字符的空间,即使其值为空或NULL也⼀样。
如果使⽤的是MylSAM表,并且各个值的长度差别不⼤,那么选⽤CHAR往往会⽐选⽤VARCHAR更好些,因为MylSAM存储引擎对固定长度⾏的处理效率,要⽐对长度可变⾏的⾼。更多相关信息在后⾯"选择利于⾼效查询的表存储格式"会介绍。
四、BINARY、VARBINARY
BINARY和VARBINARY类型与CHAR和VARCHAR相似,不同之处在于以下⼏点:
CHAR和VARCHAR都是⽤于存储字符的⾮⼆进制类型,并且都有字符集和排序规则。⽐较 操作依据的是排序序列。
BINARY和VARBINARY都是⽤于存储字节的⼆进制类型,它们没有字符集和排序规则。⽐较操作依据的是字节值的⼤⼩。
对于BINARY(M)列,当存储那些长度短于M个字节的值时,它们会⽤0x00字节进⾏补齐,以保证 长度为凡在检索时,不会去除任何内容。对于VARBINARY,在存储值时,不会进⾏补齐;在检 索时,也不会去除任何内容。
五、BLOB、TEXT
不过,TEXT类型的最⼤长度与BLOB类型的是⼀样的。也就是说 ,它们都是以字节为单位来衡量最⼤长度的,⽽不是以字节为单位(对于BLOB类型)和以字符为单位(对于TEXT类型)进⾏衡量。
BLOB和TEXT列能否被索引,具体取决于所使⽤的存储引擎:
存储引擎InnoDB和MylSAM都⽀持对BLOB和TEXT列进⾏索引。但必须指定⼀个前缀长度,以⽅便索引使⽤。这样可以避免创建出可能会过于庞⼤的索引,如果出现这样的情况,则会完全抵消掉索引所带来的好处。不过凡事有例外,TEXT列的FULLTEXT索引并不会使⽤那个前缀长度,因为FULLTEXT索引是以索引列的完整内容为基础的,指定的前缀长度会被忽略。
MEMORY表不⽀持BLOB和TEXT索引,因为MEMORY引擎根本不⽀持BLOB和TEXT列。
对于BLOB或TEXT列,需要特别注意以下⼏点:
由于BLOB和TEXT列⾥的值在长度⽅⾯的差异通常很⼤,因此在多次执⾏删除和修改操作之后,表⾥容易产⽣⼤量碎⽚。如果是使⽤MylSAM表来存储BLOB或TEXT值 ,那么定期运⾏OPTIMIZE TABLE命令可以减少碎⽚和改善系统性能。更多相关信息请参考后⾯"查询优化"相关⽂章。
max_sort_length系统变量会对BLOB和TEXT类型值的⽐较和排序操作产⽣影响。对于每个值,只有其前⾯的max_sort_length 个字节才会被使⽤到。 (这意味着,对于使⽤了多字节字符集的TEXT列,参与
⽐较 的字符数会少于max_sort_length。)如果max_sort_length的默认值 (为1024)会造成问 题,则可以在执⾏⽐较之前把它调⼤。
对于数据量⾮常⼤的值,可能需要配置MySQL服务器,增⼤max_allowed_packet参数的值。更多相关信息在后⾯"服务器调
整"⽂章会介绍。对于所有想要使⽤⼤数据量值的客户端程序,则需要在客户端增⼤数据包的⼤⼩。客户端程序mysql和
mysqldump都⽀持直接使⽤启动选项来设置这个值。
六、ENUM、SET
ENUM和SET是⽐较特殊的字符串数据类型,它们只能从⼀个固定的(预先定义好的)字符串列表⾥取值。
这两种类型的主要区别是:ENUM列值必须包含且只能包含⼀个值列表成员,⽽SET列值则允许包含任意多个值列表成员 (可以为空,也可以是全体 成员 )。换句话说,enum类型的值不允许同时出现,⽽SET类型的值允许同时出现。
在为ENUM或SET列定义合法取值列表时,必须考虑到以下⼏个因素:
这个列表确定了列的所有允许值,之前已经讨论过这⼀点。
如果ENUM或SET列带有⼀个不区分⼤⼩写的排序规则 ,那么在插⼊合法值时也不⽤区分⼤⼩写,它们都能够被识别出来 。但是,当在检索ENUM或SET列⾥的数据时 ,它们将按照列定义的合法取值列表⾥的字母⼤⼩写形式来显⽰。例如,定义了⼀个ENUM('Y', 'N')列,那么 完全可以插⼊'y'和'n';但在检索时,它们会显⽰为'Y'和'N'。如果这个列带有区分⼤⼩写的排序规则或⼆进