-
MySQL教程之MySQL体系结构和存储引擎
mysql是一个可移植的数据库,几乎能在当前所有操作系统上运行,如Linux,Mac,Windows等,尽管各种系统在底层(如线程)实现方面各有不同,但是mysql几乎能保证在各平台上的物理体系结构的一致性。
定义数据库和实例:
在数据库领域中有两个词很容易混淆,它们就是实例(instance)和数据库(database)。作为常见的数据库术语,这两个词的定义如下:
数据库:物理操作系统文件或其它形式文件类型的集合。在mysql中,数据库文件可以是frm,myd,myi,idb结尾的文件。当使用NDB引擎时,数据库的文件可能不是操作系统上的文件,而是存放于内存中的文件,但是定义仍然不变。
数据库实例:由数据库后台进程/线程以及一个共享内存区组成。共享内存可以被运行的后台进程/线程所共享。需要牢记的是,数据库实例才是真正用来操作数据库文件的。这两个词有时可以互换使用,但两者的概念完全不同。在MySQL中,实例和数据库的通常关系是一一对应的,即一个实例对应一个数据库,一个数据库对应一个实例。但是,在集群情况下可能存在一个数据库可被多个实例使用的情况。
mysql被设计为一个单进程多线程架构的数据库,这点与SqlServer比较类似,但与Oracle多进程的架构有所不同(Oracle的Windows版也是单进程多线程的架构)。这也就是说,mysql数据库实例在系统上的表现就是一个进程。当启动实例时,mysql数据库会去读取配置文件,根据配置文件的参数来启动数据库实例,这与Oracle的参数文件(spfile)相似,不同的是,在Oracle中如果没有参数文件,启动时会提示找不到该参数文件,数据库启动失败。而在mysql数据库中,可以没有配置文件,这种情况下,mysql会按照编译时的默认参数设置启动实例。
mysql体系结构
在日常生活工作中我们在谈论mysql时,即mysql也是数据库也是数据库实例,你这样理解Oracle和SqlServer可能是正确的,但对于以后理解mysql体系结构中的存储引擎可能会带来问题。从概念上说数据库是文件的集合,是依照某种数据模型组织起来并存放于二级存储器中的数据集合,数据库实例是应用程序,是位于用户与操作系统之间的一层数据库管理软件,用户对数据库数据的任何操作,包括数据库定义,数据查询,数据维护,数据库运行控制等,都是在数据库实例下进行的,应用程序只有通过数据库实例才能和数据库打交道。在直白点就是数据库是mysql存储在磁盘上的文件,当我们执行select,insert,update等操作,不能通过简单的操作文件来更改数据库的内容,需要通过数据库实例来完成对数据库的操作。
mysql表存储引擎
mysql是插件式体系结构,存储引擎是mysql区别于其它数据库的一个重要特性。存储引擎的好处是,每个存储引擎都有各自的特点,能够根据具体的应用建立不同的存储引擎表。对于开发人员来说,存储引擎对其是透明的,但了解各种存储引擎的却别对开发人员来说是有好处的。
mysql是开源的可以根据mysql预定义的存储引擎结果编写自己的存储引擎,如果你对某种存储引擎不满意,可以通过修改源码来实现自己想要的特性。下面是一些常见的存储引擎:
InnoDB存储引擎
InnoDB存储引擎支持事物,主要面向在线事物处理(OLTP)方面的应用,其特点是行锁设计,支持外键,并支持类似于Oracle的非锁定读,即默认情况下读取操作不会产生锁。mysql在Windows版本下innoDB是默认存储引擎,同时innoDB默认被包含在所有的mysql二进制发布版本中。
innoDB存储引擎将数据放在一个逻辑的表空间中,这个表空间就像黑盒一样由innoDB自身进行管理。它可以将每个innoDB存储引擎的表单独存放到一个独立的idb文件中,与Oracle类似,innoDB存储引擎同样可以使用裸设备来建立表空间。
innoDB通过使用多版本并发控制(MVCC)来获得高并发性,并且实现了sql标准的4种隔离级别,默认为REPEATABLE级别,同时使用一种被称为next-key locking的策略来避免幻读(phantom)现象的产生。除此之外,innoDB存储引擎还提供了插入缓冲(insert buffer),二次写(double write),自适应哈希索引(adaptive hash index),预读(read ahead)等高性能和高可用的功能。
对于表中的存储,innoDB存储引擎采用了聚集(clustered)的方式,这种方式类似于Oracle的索引聚集表(index organized table,IOT)。每张表的存储都按主键的顺序存放,如果没有显示的在表定义时指定主键,innoDB存储引擎会为每一行生成一个6字节的ROWID,并以此作为主键。
MyISAM存储引擎
MyISAM存储引擎时mysql官方提供的存储引擎,其特点是不支持事物,表锁和全文索引,对于一些OLAM(online analytical processing 在线分析处理)操作速度快。除Windows版本外,是所有mysql版本默认的存储引擎。
MyISAM存储引擎表由MYD和MYI组成,MYD用来存放数据文件,MYI用来存放索引文件。可以通过使用myisampack工具来进一步压缩数据文件,因为myisampack工具使用赫夫曼编码静态算法来压缩数据,因此使用myisampack工具压缩后的表示只读的,当然你也可以通过myisampack来解压数据文件。
在mysql5.0版本以前,MyISAM默认支持的表大小为4G,如果需要支持大于4G的MyISAM表时,需要指定MAX_ROWS和AVG_ROW_LENGTH属性。mysql5.0版本开始,MyISAM默认支持256T的单表数据,这足够满足一般应用的需求。
NDB存储引擎
NDB存储引擎是一个集群存储引擎,类似于Oracle的RAC集群。不过与Oracle RAC share everything结构不同的是,其结构是share nothing的集群架构,因此还能提供更高级别的高可用性。NDB的特点是数据全部放在内存中,因此主键查找(primary key lookup)的速度极快,并且通过添加NDB数据存储节点(data node)可以线性的提高数据库性能,是高可用,高性能的集群系统。
NDB存储引擎的连接操作时在mysql数据库层完成的,而不是在存储引擎层完成的,这意味着,复杂的连接操作需要巨大的网络开销,因此查询速度很慢。
Memory存储引擎
memory存储引擎将表中的数据存放在内存中,如果数据库重启或发生崩溃,表中的数据都将消失。它非常适合用于存储临时数据的临时表,以及数据库中的纬度表。它默认使用哈希索引,而不是我们熟悉的B+树索引。
虽然memory存储引擎速度非常快,但在使用上还是有一定的限制。比如其只支持表锁,并发性能较差,并且不支持TEXT和BLOB列类型。最重要的是,存储变长字段(varchar)时是按照定长字段(char)的方式进行的,因此会浪费内存。
此外有一点长被忽略的是,mysql数据库使用memory存储引擎作为临时表来存放查询的中间结果集。如果中间结果集大于memory存储引擎表的容量设置,又或者中间结果含有TEXT或BLOB列类型字段,则mysql数据库会把其转换到MyISAM存储引擎表而存放到磁盘。
Archive存储引擎
archive存储引擎只支持INSERT和SELECT操作,mysql5.1开始支持索引。其使用zlib算法将数据行进行压缩后存储,压缩比率一般可达1:10.正如其名称所示,archive存储引擎非常适合存储归档数据,如日志信息。archive存储引擎使用行锁来实现高并发的插入操作,但是本身并不是事物安全的存储引擎,其设计目标主要是提供高速的插入和压缩功能。
federated存储引擎
federated存储引擎表并不存放数据,它只是指向一台远程mysql数据库服务器上的表。这非常类似于sql server的连接服务器和Oracle的透明网管,不同的是,当前federated存储引擎只支持mysql数据库表,不支持异构数据库表。
Maria存储引擎
Maria存储引擎时新开发的引擎,设计目标主要是用来取代原有的MyISAM存储引擎,从而成为mysql的默认存储引擎,其特点是缓存数据和索引文件,航所设计,提供MVCC功能,支持事物和非事物安全的选项支持,以及更好的OLOB字符类型的处理性能。