字符串类型()
MySQL 支持多种字符串类型每种类型还有很多变种这些数据类型在 和 版本发生了很大的变化使得情况更加复杂从MySQL 开始每个字符串列可以定义自己的字符集和排序规则或者说校对规则(collation)(更多关于这个主题的信息请参考第 章)这些东西会很大程度上影响性能
VARCHAR 和CHAR 类型
VARCHAR 和CHAR 是两种最主要的字符串类型不幸的是很难精确地解释这些值是怎么存储在磁盘和内存中的因为这跟存储引擎的具体实现有关下面的描述假设使用的存储引擎是InnoDB 和/ 或者MyISAM如果使用的不是这两种存储引擎请参考所使用的存储引擎的文档
先看看VARCHAR 和CHAR 值通常在磁盘上怎么存储请注意存储引擎存储CHAR 或者VARCHAR 值的方式在内存中和在磁盘上可能不一样所以MySQL 服务器从存储引擎读出的值可能需要转换为另一种存储格式下面是关于两种类型的一些比较
VARCHAR
VARCHAR 类型用于存储可变长字符串是最常见的字符串数据类型它比定长类型更节省空间因为它仅使用必要的空间(例如越短的字符串使用越少的空间)有一种情况例外如果MySQL 表使用ROW_FORMAT=FIXED 创建的话每一行都会使用定长存储这会很浪费空间
VARCHAR 需要使用 或 个额外字节记录字符串的长度如果列的最大长度小于或等于 字节则只使用 个字节表示否则使用 个字节假设采用latin 字符集一个VARCHAR() 的列需要 个字节的存储空间VARCHAR() 的列则需要个字节因为需要 个字节存储长度信息
VARCHAR 节省了存储空间所以对性能也有帮助但是由于行是变长的在UPDATE 时可能使行变得比原来更长这就导致需要做额外的工作如果一个行占用的空间增长并且在页内没有更多的空间可以存储在这种情况下不同的存储引擎的处理方式是不一样的例如MyISAM 会将行拆成不同的片段存储InnoDB则需要分裂页来使行可以放进页内其他一些存储引擎也许从不在原数据位置更新数据
下面这些情况下使用VARCHAR 是合适的字符串列的最大长度比平均长度大很多列的更新很少所以碎片不是问题使用了像UTF 这样复杂的字符集每个字符都使用不同的字节数进行存储
在 或者更高版本MySQL 在存储和检索时会保留末尾空格但在 或更老的版本MySQL 会剔除末尾空格
InnoDB 则更灵活它可以把过长的VARCHAR 存储为BLOB我们稍后讨论这个问题
CHAR
CHAR 类型是定长的MySQL 总是根据定义的字符串长度分配足够的空间当存储CHAR 值时MySQL 会删除所有的末尾空格(在MySQL 和更老版本中VARCHAR也是这样实现的也就是说这些版本中CHAR 和VARCHAR 在逻辑上是一样的区别只是在存储格式上)CHAR 值会根据需要采用空格进行填充以方便比较
CHAR 适合存储很短的字符串或者所有值都接近同一个长度例如CHAR 非常适合存储密码的MD 值因为这是一个定长的值对于经常变更的数据CHAR 也比VARCHAR 更好因为定长的CHAR 类型不容易产生碎片对于非常短的列CHAR 比VARCHAR 在存储空间上也更有效率例如用CHAR() 来存储只有Y 和N 的值如果采用单字节字符集注 只需要一个字节但是VARCHAR() 却需要两个字节因为还有一个记录长度的额外字节
CHAR 类型的这些行为可能有一点难以理解下面通过一个具体的例子来说明首先我们创建一张只有一个CHAR() 字段的表并且往里面插入一些值
当检索这些值的时候会发现string 末尾的空格被截断了
如果用VARCHAR() 字段存储相同的值可以得到如下结果
数据如何存储取决于存储引擎并非所有的存储引擎都会按照相同的方式处理定长和变长的字符串Memory 引擎只支持定长的行即使有变长字段也会根据最大长度分配最大空间不过填充和截取空格的行为在不同存储引擎都是一样的因为这是在MySQL 服务器层进行处理的
返回目录高性能MySQL
编辑推荐
ASPNET MVC 框架揭秘
Oracle索引技术
ASP NET开发培训视频教程
数据仓库与数据挖掘培训视频教程