CHAR定长字段对MyISAM和InnoDB的意…

来源:互联网 发布:单向链表反转 java 编辑:程序博客网 时间:2024/05/29 04:47
先看看在MyISAM中的情况:

对于MyISAM而言,如果没有VARCHAR,TEXT等变长类型,那么每行数据所占用的空间都是定长的(Fixed),俗称静态表,相对应的就是动态表。

当执行一次查询时,MySQL可以通过索引文件找到所需内容的实际行号,此时,由于每行数据所占用的空间都是定长的(Fixed),所以可以通过查询到的实际行号直接定位到数据文件的具体位置,比如说查询到的实际行号是10,而一行实际占用的空间是1000byte,那么立刻就能知道所需数据的地址是位于10*1000=10000byte的位置,形象一点来说,就是直接可以大踏步的跨越数据文件,而不用从头一点点的扫描数据文件。相对应的,如果行长度是变化的,那么就不能这样计算。所以说静态表提高的效率(提示:使用MyISAM时,MySQL把数据和索引分别保存在独立的文件里)。

所以说CHAR定长字段对MyISAM意义很大,必须重视。

再看看在InnoDB中的情况:

对于InnoDB而言,数据行是没有所谓定长与否的概念的,这是由其结构所决定的:在InnoDB中,数据就位于PrimaryKey的B-Tree叶节点之上,而除Primary Key之外的索引被称为Secondary Index,它们直接指向PrimaryKey。

当执行一次查询时,通过Primary Key查询的情况自不用谈,即便是通过SecondaryIndex查询,由于它们直接指向Primary Key,所以也会直接定位到Primary Key,至于数据,就位于PrimaryKey的叶节点之上,也就是说,只要定位到了PrimaryKey,就等同于已经找到了数据,如此一来,就不需要MyISAM中定长的意义了。

所以说CHAR定长字段对InnoDB意义很小,可以忽视。

=============================

引申一点来看待这个问题:如果使用类似主服务器是InnoDB,从服务器是MyISAM这样的主从结构,那么就有必要针对不同的表类型考虑CHAR的取舍,头脑中应该一直有这样的概念,不要想当然的认为主从服务器中表的字段类型必须一致。

下面在记录几个可能对读者有帮助的文章:

MyISAM 索引结构了解 - MyISAM Index Structure
Innodb 索引结构了解 - Innodb Index Structure

既然说到了字段类型,就再说点别的:如果表中有TEXT、BLOB字段,那么临时表只能生成在磁盘上,这无疑是个严重的问题,查询时使用SUBSTRING把TEXT,BLOG转换成STRING能在一定程度上缓解这个问题,不过更好的方法是分表,把TEXT,BLOB类型的字段分离到独立的表中,什么时候进行这种分离?有一个简单的判断标准,看你是否需要对这个表进行类似分页的查询,如果有这样的SQL,就应该分离TEXT,BLOB,如果仅仅是KEY,VALUE形式的查询,就不必分离TEXT,BLOB,因为KEY,VALUE形式的查询不会产生临时表。