TIMESTAMP存储的范围比DATETIME要小,但是空间利用率也最高。MySQL支持的时间精度最高为1s,如果更精确的存储,就必须自己定义存储格式了。

1.2 字符串类型

MySQL中的字符串类型比较多也比较的复杂,各个字符串类型的差别不仅仅在存储时候的空间占用,对存取时候字段某位的strip和padding还有差异。

对于类型CHAR/VARCHAR/TEXT是跟本地字符集相关的,这会影响到实际占用空间的字节数、字符比较等。

CHAR(M)/VARCHAR(M)

长度限制参数M表示的是本地字符集的字符个数而不是bytes数目,比如对于UTF8编码,每个本地字符其实际占用的byte长度可能是3或4倍的本地字符长度。比如VARCHAR(255),如果每个本地字符占用两个字节,那么其需要的存储空间最大为255×2+2。

CHAR的M被限制在最大255,而VARCHAR的M理论上受限于Row Size的长度(65,535bytes),且实际存储时候会附加1~2字节的前缀表示数据实际长度。如果strict SQL模式没有被打开,那么当插入数据超过声明长度限制的时候,数据将会被截断并产生警告信息,在strict SQL模式下将会出错。

CHAR类型在存储的时候mysql数据类型,会在右端padding SPACE到指定的M长度,当取该字段的时候,所有末尾的SPACE都将会被strip掉然后返回;VARCHAR不会对进行SPACE进行padding以及strip操作,存储什么样的数据就会返回什么样的数据。

对于CHAR/VARCHAR/TEXT类型,在进行字符串比较的时候,(SQL语句参数中的字符串)结尾的空格都是不参与比较的,但是对于LIKE语句,检索的时候结尾的空格是考虑在内的。

BINARY(M)/VARBINARY(M)

BINARY/VARBINARY在操作的时候,参考的是byte streaming而不是charaset streaming,所以其长度限制参数M表示的是byte数目,在比较的时候也是直接的数字大小比较(而非本地字符集方式比较)。

BINARY在插入的时候,会使用0x00(而非SPACE)padding到长度M,取值的时候不会进行strip尾部空字符的操作(意味着取出来的长度一定是M);VARBINARY则是保证原样存取的。

BLOB/TEXT

分别有TINY/MEDIUM/LONG类型的衍生长度,BLOB是bytes streaming类型的,而TEXT是基于character streaming本地字符集类型的,两者在存取的时候都不会进行padding和strip操作。

BLOB/TEXT的关系和之前的VARBINARY/VARCHAR是比较相似的,除了:BLOB/TEXT不能够有DEFAULT值;BLOB/TEXT在创建索引的时候必须要有prefix length,而前者是可选的;给予TEXT索引需要有前缀长度,而且建立索引会自动padding SPACE到索引长度,所以如果插入的字符前面一样,只是尾部空字符长度不同,也是会产生相同的索引值。

字符串各个类型占用的空间长度

类型

长度

CHAR(M)

Mxw bytes

BINARY(M)

M bytes

VARCHAR(M), VARBINARY(M)

L+1/L+2 bytes

TINYBLOB, TINYTEXT

L+1 bytes

LOB, TEXT

L+2 bytes

MEDIUMBLOB, MEDIUMTEXT

L+3 bytes

LONGBLOB, LONGTEXT

L+4 bytes

根据官方手册mysql数据类型,CHAR/BINARY及其衍生的类型的数据是存储在表的行内部(inline)的,而对于BLOB和TEXT类型,每一个字段只占用该行9-12(1~4+8)个字节(用于数据的地址和长度),实际的数据是存储在Row Buffer之外位置的。所以对于经常访问的字符串类型,而长度又不是特别的大,还是建议用VARCHAR(M)的数据类型,性能会比TEXT快不少。

2. MySQL数据库索引

数据库索引可以用来快速找到需要的行,否则的话MySQL就需要一行一行的遍历,查询效率自然相当的低。

MySQL支持的索引包括PRIMARY KEY、UNIQUE、INDEX、FULLTEXT类型的索引。前面说过,FULLTEXT类型的全文索引在中文下基本是报废的,在此就不予讨论了。

特别注意的是,对于索引列只能使用单纯的列名,而不能是表达式或者函数的一部分,比如age+2、TO_DAYS(date_col),引擎在检索的时候才能使用索引。

2.1 索引的类型

PRIMARY KEY

在InnoDB内部,表数据是优化主键快速查询而排列分布的,其查找速度是最快的(相当于聚簇索引:该索引中键值的逻辑顺序决定了表中相应行的物理顺序)。即使表中没有适合做主键的列,也推荐采用一个自动增长的整数主键(代理键),那么这个表在增加数据的时候是顺序存放的,而且后续在别的表参考该外键查询的时候也会得到优化。本身在设计表的时候,也建议常用的数据额不常用的数据分表存放以增加效率。

INDEX

普通索引,对数据没有约束要求,多行记录可以包含相同值。无论对于字符串索引,还是多列组合索引,都以及在查询语句中,都有个最左前缀的原则:

(1) 对于字符串类型,可以指定索引前缀长度(且对于BLOB/TEXT前缀长度参数是必须的),在InnoDB表中其前缀长度最长是767 bytes,且参数M是用bytes计量的。所以太长的字符串,建立BTree索引浪费比较大,这时候用手动模拟HASH索引是个方法,不过这种方式对字符串无法灵活的使用前缀方式查询(例如LIKE这类的操作)。

(2) 在建立多列索引的时候,必须按照从左到右的顺序使用全部或部分的索引列,才能充分的使用组合索引,比如:(col1, col2, col3)使用(col1)、(col1, col2)、(col1, col2, col3)有效。在查询语句中会一直向右匹配直到遇到范围查询(>,

———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,会员只需98元,全站资源免费下载
站 长 微 信: wufeng502749642