在 MySQL 中,只有一种 Join 算法,就是大名鼎鼎的 Nested Loop Join,他没有其他很多数据库所提供的 Hash Join,也没有 Sort Merge Join。顾名思义,Nested Loop Join 实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有第三个参与 Join,则再通过前两个表的 Join 结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复。
还是通过示例和图解来说明吧,后面将通过我个人数据库测试环境中的一个 example(自行设计,非MySQL 自己提供) 数据库中的三个表的 Join 查询来进行示例。
注意:由于这里有些内容需要在MySQL 5.1.18之后的版本中才会体现出来,所以本测试的MySQL 版本为5.1.26
表结构:
sky@localhost : example 11:09:32> show create table user_groupG*************************** 1. row ***************************Table: user_groupCreate Table: CREATE TABLE `user_group` (`user_id` int(11) NOT NULL,`group_id` int(11) NOT NULL,`user_type` int(11) NOT NULL,`gmt_create` datetime NOT NULL,`gmt_modified` datetime [...]

, , ,

早上同事问我在哪里可以找到 MySQL 的客户端安装包,他需要在一台 Oracle 数据库主机上面安装 MySQL 的客户端包做一些事情。当我打开 MySQL 官方网站下载频道页面的时候,眼前出现了让我比较惊讶的内容,截图如下:

看出究竟了吧,还没有?那看来你并不是很经常或者并不是很关注 MySQL 各个版本的发展情况。 MySQL Comunnity Server 默认的下载版本已经从 MySQL 5.0 GA 换成 MySQL 5.1 GA 了,已经明确标识为:
Current Release (Recommended)
MySQL 5.1—Generally Available (GA) release for production use

Upcoming Releases
MySQL 6.0 — Alpha
MySQL Maria Preview
Snapshots — source code snapshots of the development trees
Glassfish+MySQL bundle — developers edition

Older Releases
MySQL 5.0 — [...]

,

在此之前曾经写过一篇介绍 “Innodb 索引结构了解 – Innodb Index Structure” 的文章,这次再接着分析一下 MyISAM 存储引擎索引的基本存储结构。
从索引基本的存放数据结构来说,MyISAM 的索引不论是 Primary Key 还是普通 Index,存储结构都基本一样,基本结构都是 Balance Tree (简称为 B-Tree),所有的键值详细信息和行“指针”信息都存放于 B-Tree 的 Leaf Nodes 上面。这个基本的数据结构和 MySQL 的其他存储引擎如 Innodb 也基本相同。但是,MyISAM 的索引并不像 Innodb 存储引擎那样 Primary Key 和 Secondary Index 中存放的数据存在较大区别。在 MyISAM 存储引擎中,Primary Key 和其他的普通 Index 的主要区别仅仅在于 Primary Key 的索引键需要满足是非空的唯一值而已,另外一个区别其实也是每一个普通索引之间都存在的区别,就是整个索引树的键值排列顺序不太一样。
由于 MyISAM 存储引擎中数据行的存储分为固定长度和动态长度两种,所以在 MyISAM 存储引擎的数据文件中定位一行数据所需要信息也存在两种方式。一种是直接通过行号(row number)来定位固定长度表数据的行,另外一种是通过其他一些相对的文件位置标识信息来定位动态长度表数据的行,这里我们姑且将两种方式统称为RID(Row ID)吧。
下面这张图片展示了 MyISAM 索引的基本存储方式:

, , ,

总的来说,在 MySQL 中的ORDER BY有两种排序实现方式,一种是利用有序索引获取有序数据,另一种则是通过相应的排序算法,将取得的数据在内存中进行排序。
下面将通过实例分析两种排序实现方式及实现图解:
假设有 Table A 和 B 两个表结构分别如下:
sky@localhost : example 01:48:21> show create table A\G*************************** 1. row ***************************Table: ACreate Table: CREATE TABLE `A` (`c1` int(11) NOT NULL default ‘0′,`c2` char(2) default NULL,`c3` varchar(16) default NULL,`c4` datetime default NULL,PRIMARY KEY  (`c1`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 sky@localhost : example 01:48:32> show create table B\G*************************** 1. row ***************************Table: BCreate [...]

, ,

Innodb 作为 MySQL 中使用最为广泛的 事务型存储引擎,不仅在事务实现数据版本控制方面和其他存储引擎有一定的区别,其数据结构也是以非常有特点的方式存储的。
每个Innodb表的数据其实可以说就是以一个树型(B-Tree)结构存储的,表的数据和主键(Primary Key)共同组成了一个索引结构,也就是我们常说的Innodb的Clustered Primary Key。在这个Clustered Primary Key中,Leaf Nodes其实就是实际的表记录,我们常规理解上的索引信息全部在Branch Nodes上面。
除了Clustered Primary Key之外的其他所有索引在Innodb中被称为Secondary Index。Secondary Index就和普通的B-Tree索引差不多了,只不过在Secondary Index的所有Leaf Nodes上面同时包含了所指向数据记录的主键信息,而不是直接指向数据记录的位置信息。
所以,在 Innodb 中,如果主键值占用存储空间较大的话,会直接影响整个存储 Innodb 表所需要的物理空间,同时也会直接影响到 Innodb 的查询性能。
下面是画的一张 Innodb 索引基本结构图,包括 Primary Key 和 Secondary Index 两种索引的比较。

, , ,