MySQL是一个可移植的数据库,几乎能在当今所有的操作系统上运行,如Linux、Mac、Windows、Solaris、FreeBSD等。各种操作系统在底层实现(如线程)上各不相同,MySQL却能保证在各平台上物理体系结构的一致性。
数据库(database)和实例(instance)的概念
数据库:物理操作系统文件或者其他形式文件类型的集合。MySQL中,数据库文件可以是frm、myd、myi和ibd结尾的文件。使用NDB引擎时,数据库文件可能不是操作系统上的文件,而是存放在内存中的文件。
数据库实例:由数据库后台进程/线程以及一个共享内存区组成。共享内存可以被数据库后台进程/线程共享。数据库实例是真正用来操作数据库文件的。
在MySQL中,实例和数据库的关系是一一对应的。在集群状态下可能存在一个数据库被多个实例使用的情况。
从概念上说,数据库是文件(一般来说是二进制文件)的集合,是由一个个文件组成的,是按照某种数据模型组织起来并存放于二级存储器中的数据集合;数据库实例是应用程序,是位于用户与操作系统之间的一层数据管理软件,用户对数据库的任何操作(包括数据库的定义、查询、数据维护、数据库运行控制)都是由数据库实例来完成,其它应用程序只能通过与数据库实例进行交互才能访问数据库。即要对数据库中的一个个文件进行SELECT、INSERT、UPDATA和DELETE操作,不能直接通过操作文件来更改数据库中的内容,而是要通过数据库实例来完成对数据库的操作。
MySQL是一个单进程多线程结构的数据库。与SQL Server类似,与Oracle多进程的架构不同(Oracle的Windows版本也是单进程多线程架构)。MySQL数据库实例在操作系统上的表现就是一个进程。
MySQL体系结构
常见问题:
为什么MySQL不支持全文索引?
MySQL速度快是因为它不支持事务吗?
当表数据量大于1000W时,MySQL的性能会急剧下降吗?
解决这些问题需要理解MySQL数据库的体系结构。
MySQL由以下几个部分组成:
- 连接池组件(connection pool)
- 管理服务和工具组件(Management services and utilities)
- SQL接口组件(SQL interface)
- 查询分析组件(parser,解析)
- 优化器组件(optimizer)
- 缓冲(cache)组件
- 插件式存储引擎(pluggable storage engine)
- 物理文件 (files)
存储引擎是基于表的,不是数据库。MySQL区别于其他数据库的最重要的特点是其插件式的表存储器,插件式表存储器架构提供了一系列标准的管理和服务支持,这些标准和存储引擎本身无关,其中一些可能是每个数据库系统必须的,例如SQL分析器与优化器,存储引擎是底层物理结构的实现,其开发实现各不相同。
MySQL表存储引擎
插件式体系结构是MySQL数据库独有的,存储引擎是MySQL区别于其他数据库的最重要的特性,是MySQL数据库的核心。使用存储引擎的好处是在我们使用MySQL的过程中,能根据具体应用的不同,采用不同特点的存储引擎来建立不同的存储引擎表。
MySQL是开源的,我们可以根据MySQL预定义的存储引擎接口编写自己的存储引擎,如果我们对某种存储引擎不满意,也可以修改其源码来实现自己想要的特性。MySQL的存储引擎可以分为官方存储引擎和第三方存储引擎,InnoDB存储引擎就属于第三方存储引擎(Oracle收购)。
1 InnoDB存储引擎
InnoDB支持事务,主要面向在线事务处理(OLTP, online transaction processing)方面的应用。其特点是行锁设计、支持外键,支持类似于Oracle的非锁定读(默认情况下读取操作不会产生锁)。是MySQL在Windows版本下的默认存储引擎,也被默认地包含在所有MySQL二进制的发布版本中。
InnoDB将数据存放在一个逻辑表空间中,这个表空间就像一个黑盒一样由InnoDB自身进行管理。从MySQL4.1版本开始,每个InnoDB存储引擎的表可以被单独存放到一个独立的ibd文件中。与Oracle类似,InnoDB存储引擎同样可以使用裸设备(row disk)来建立其表空间。
InnoDB通过多版本并发控制(MVCC, multi-version concurrency control)来获得高并发性,而且实现了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,以此作为主键。
2 MyISAM存储引擎
MyISAM存储引擎是MySQL官方提供的存储引擎。特点是不支持事务、表锁和全文索引,对于一些OLAP(online analytical processing,在线分析处理)操作速度快。除Windows版本外,MyISAM是所有MySQL的默认存储引擎。
MyISAM存储引擎表由MYD和MYI组成,MYD用来存放数据文件,MYI用来存放索引文件。可以通过使用myisampack工具来进一步压缩数据文件(压缩后可以用myisampack解压),myisampack使用霍夫曼(Huffman)编码静态算法来压缩数据,所以用它压缩后的表示只读的。
在MySQL5.0版本之前,MyISAM默认支持的表大小为4G,如果需要支持大于4G的MyISAM表时,需要指定MAX_ROWS和AVG_ROW_LENGTH属性。从MySQL5.0版本开始,MyISAM默认支持256T的单表数据,足以满足一般需求。
对于MyISAM存储引擎表,MySQL只缓存其索引文件,数据文件的缓存交由操作系统本身完成,而其他大部分数据库使用LRU算法缓存数据,与MyISAM不同。在MySQL 5.1.23版本之前,无论是在32位还是64位操作系统环境下,缓存索引的缓冲区最大只能设置为4G,之后的版本中,64位操作系统支持大于4G的索引缓冲区。
3 NDB存储引擎
NDB存储引擎是一个集群存储引擎,类似于Oracle的RAC集群,与RAC share everything结构不同的是,NDB的结构是share nothing的集群结构,能提供更高级别的可用性。NDB的特点是数据全部放在内存中(从5.1版本开始,可以将非索引数据放在磁盘上),因此主键查找(primary key lookup)速度极快,并且通过添加NDB数据存储节点(data node)可以线性地提高数据库性能,是高可用高性能的集群系统。
NDB存储引擎的连接操作(JOIN)是在MySQL数据库层而不是存储引擎层完成的。这意味着复杂的连接操作需要巨大的网络开销,所有查询速度很慢。
4 Memory存储引擎
Memory存储引擎(之前称为HEAP存储引擎)将表中的数据存放在内存中,如果数据库重启或发生崩溃,表中的数据都将消失。Memory非常适用于存储临时数据的临时表和数据仓库中的纬度表。Memory默认使用哈希索引而不是一般的B+树索引。
Memory存储引擎优点是速度非常快,缺点是只支持表锁,并发性能差;而且不支持TEXT(用来保存字符数据)和BLOB(用来保存二进制数据)列类型;其存储变长字段(varchar)时是按照定长字段(char)的方式进行的,会浪费内存。(eBay的Igor Chernyshev给出了Patch方案)
MySQL数据库使用Memory存储引擎作为临时表来存放查询的中间结果集(intermedia result),如果中间结果集大于Memory存储引擎表的容量设置,或者中间结果集含有TEXT或者BLOB列类型字段,则MySQL数据库会把其转换到MyISAM存储引擎表而存放到磁盘。因为MyISAM不缓存数据文件,所以此时产生的临时表的查询性能会下降。
5 Archive存储引擎
Archive存储引擎只支持INSERT和SELECT操作,从MySQL5.1版本开始支持索引。使用zlib算法将数据行(row)进行压缩后存储,压缩比率一般高达1:10。Archive存储引擎非常适合存储归档数据,如日志信息。Archive使用行锁来实现高并发的插入操作,但它本身并不是事务安全的存储引擎,其设计目标主要是提供高速的插入和压缩功能。
6 Federated存储引擎
Federated存储引擎表并不存放数据,它只是指向一台远程MySQL数据库服务器上的表,类似于SQL Server的链接服务器和Oracle的透明网关,不同的是当前Federated存储引擎只支持MySQL数据库表,不支持易购数据库表。
7 Maria存储引擎
Maria的设计目标是用来取代原有的MyISAM存储引擎,从而成为MySQL的默认存储引擎,它可以看成是MyISAM的后续版本。特点是缓存数据和索引文件,行锁设计,提供MVCC功能,支持事务和非事务安全的选项支持,更好的BLOB字符类型的处理性能。
8 其他存储引擎
上面7种存储之外还有Merge、CSV、Sphinx和Infobright等,它们有各自适用的场景。
几个问题的回答:
为什么MySQL不支持全文索引?MySQL支持全文索引,MyISAM、Sphinx等存储引擎都支持全文索引。
MySQL速度快是因为它不支持事务吗?不是,MySQL中MyISAM存储引擎不支持事务,但是InnoDB支持。速度快要针对不同的应用场景,对于ETL(extract-transform-load, 数据抽取-转换-装载)操作,MyISAM有优势。
当表的数据量大于1000W时,MySQL的性能会急剧下降吗?不会,MySQL是数据库,不是文件,随着数据行数的增加,MySQL的性能会有所下降,但是这样的性能下降不是线性的。选择合适的存储引擎和配置,再大的数据量MySQL也能承受。案例:Mytrix在InnoDB上存储了超过1TB的数据;一些网站使用InnoDB存储引擎处理平均每秒800次的插入/更新操作。
各种存储引擎之间的比较
存储引擎是MySQL体系结构的核心。
不同MySQL存储引擎相关特性比较:
Feature | MyISAM | BDB | Memory | InnoDB | Archive | NDB |
---|---|---|---|---|---|---|
Storage Limits | No | No | Yes | 64TB | No | Yes |
Transactions(commit,rollback,etc.) | Yes | Yes | ||||
Locking granularity(锁粒度) | Table | Page | Table | Row | Row | Row |
MVCC/Snapshot Read(快照读) | Yes | Yes | Yes | |||
Geospatial support(地理空间支持,数据对象定义在几何空间中) | Yes | |||||
B-Tree indexes | Yes | Yes | Yes | Yes | Yes | |
Hash indexes | Yes | Yes | Yes | |||
Full text search index | Yes | |||||
Clustered index | Yes | |||||
Data Caches | Yes | Yes | Yes | |||
Index Caches | Yes | Yes | Yes | Yes |
MySQL的设计者认为不是所有的应用都需要事务,所以存在不支持事务的存储引擎。可以通过SHOW ENGINES语句查看当前使用的MySQL数据库支持的存储引擎,也可以通过information_schema架构下的ENGINES表来查看。