数据类型之字符串

数据类型之字符串

    varchar和char是两种最主要的字符串类型。

    这些值在磁盘和内存中如何存储,要根据存储引擎的具体实现。

    存储引擎存储char活着varchar值的方式在内存中和磁盘上可能不一样。

    varchar用于存储可变长字符串。它比订场类型更节省空间。有一种例外,如果是用了row_format=fixed创建,那么每一行都会使用定长存储。

    varchar需要使用1或2个额外字节记录字符串长度,如果列的最大长度小于或等于255字节,使用1个字节表示,否则使用2个字节表示。

    因为行是变长的,在update时可能使行变得比原来更长,这就导致需要额外的工作。

    如果一行占用的空间增长,并且在页内没有更多的空间可以存储,在这种情况下,不同存储引擎的处理方式是不一样的。

    MyISAM会将行拆成不同的片段处处,InnoDB则需要分裂页来式行可以放进业内。

    varchar大致适合下列的情况:

        字符串的列最大长度比平均长度大很多

        列更新的很少(所以碎片不是问题)

        是用了向UTF-8这样复杂的字符集,每个字符都使用不同的字节数进行存储

        MySQL 5.0或更高版本,存储和检索时会保留末尾空格。早期版本会剔除末尾空格。InnoDB则更灵活,它可以把过长的varchar存储为BLOB。

char类型是定长的。

        当存储char值时,MySQL会剔除所有的末尾空格。char值会根据需要采用空格进行填充以方便比较。

        char是个存储很短的字符串,活着所有值都接近同一个长度。例如char非常适合存储密码的md5值。

        对于经常变更的数据,char也比varchar更好,订场的char类型不容易产生碎片。

       对于非常短的列,char比varchar在存储空间上也更有效率。比如char(1)只需要1个字节,而varchar(1)则需要2个字节。

        与char和varchar类似的还有binary和varbinary,他们存储的是二进制字符串。只不过二进制字符串存储的是字节码而不是字符。填充也不一样:MySQL填充binary采用的是\0(零字节)而不是空格,检索时也不会去掉填充

        当希望使用字节码而不是字符进行比较时,这些类型非常有用。比较binary字符串时,每次按一个字节,并且根据字节的数值进行比较。

       二进制比较字符比较简单,更快。

 

blob和text都是为春初很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。

        他们分别属于两组不同的数据类型家族:

        字符类型包括tinytext,smalltext,text,mediumtext,longtext

        二进制类型包括tinyblob,smallblob,blob,mediumblob,longblob

        MySQL把每一个blob和text值当做一个独立的对象处理。当值太大时,innoDB会使用专门的外部存储区域存储实际的值。

       blob和text家族之间仅有的不同是blob类型处处的是 二进制数据,没有排序规则或字符集,而text类型有字符集和排序规则。

        MySQL对blob和text列进行排序与其他类型不同:它只对每列的最前max_sort_length字节而不是整个字符串做排序。如果只需要排序前面一小部分,则可以缩减max_sort_length的配置活着使用order by substring(column,lenth)。

 

枚举(enum)

        有时候可以使用枚举列代替常用的字符串。

        枚举列可以把一些不重复的字符串处处成一个预定义的集合。枚举在处处时非常紧凑,会根绝列表值得数量压缩到1个活着2个字节中。MySQL在内部将每个值在列表中的位置报出为整数,丙子额在标的.frm文件中保存“数字-字符串”映射关系的查找表。

        如果一个表中的字段e是枚举类型(有三个值,a,b,c),表内插入该字段值分别是a,b,c三条记录

        查询如下:select e+0 from test;

        查询结果:

+---------+

|  e + 0  |

|       1    |

|       3    |

|       2    |

+---------+

        如果使用数字作为enum枚举常量,这种双重性很容易导致混乱,例如enum('1','2','3'),建议避免。

        查询如下:select e from test;

        查询结果:

+---------+

|  e         |

|     a      |

|     b      |

|     c      |

+---------+

        一种绕过这种现实的方式是按照需要的顺序来定义枚举列。也可以在查询中使用field()函数现实的指定排序顺序,但这回导致无法利用索引消除排序。

select e from text order by field(e,'a','b','c')

 

        枚举最不好的地方是,字符串列表是固定的,添加活着删除字符串必须使用alter table。

        对于一些列未来可能会改变的字符串,使用枚举不太好,除非能接受在列表末尾添加元素,这样就可以不用重建整个表来完成修改。

        因为枚举值保存为证书,并且必须尽心查找才能转换为字符串,所以没剧烈有一些开销。通常没剧烈都比较小,所以开销还可以控制。

特殊情况,char和varchar与枚举列关联可能比直接跟char或varchar关联还要慢。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值