MySQL存储引擎
介绍
MySQL 提供了多个不同的存储引擎,包括处理事务安全表的引擎和处理非事务安全表的引擎。
可以使用''SHOW ENGINES;''命令查看当前版本的MySQL所支持的引擎类型,如MySQL8支持的存储引擎有 InnoDB、MyISAM、Memory、Merge、Archive、CSV、BLACKHOLE 等。
存储引擎 | 描述 |
---|---|
ARCHIVE | 用于数据存档的引擎,数据被插入后就不能在修改了,且不支持索引。 |
CSV | 在存储数据时,会以逗号作为数据项之间的分隔符。 |
BLACKHOLE | 会丢弃写操作,该操作会返回空内容。 |
FEDERATED | 将数据存储在远程数据库中,用来访问远程表的存储引擎。 |
InnoDB | 具备外键支持功能的事务处理引擎 |
MEMORY | 置于内存的表 |
MERGE | 用来管理由多个 MyISAM 表构成的表集合 |
MyISAM | 主要的非事务处理存储引擎 |
NDB | MySQL 集群专用存储引擎 |
当然,不同的存储引擎有着不同的特性和适用场景,以下是一些MySQL存储引擎的使用场景举例:
InnoDB:适用于对事务支持、灵活性、可靠性和容错性要求较高的应用,例如常见的管理系统、金融系统等。
MyISAM:适用于读密集、写少的场景,例如新闻、博客等发布式的网站。
MEMORY:适用于基于内存的临时表和缓存表,它可以显著减少I/O次数,并且具有快速的读写速度。这种存储引擎适用于小型临时表或者与表达式相关的计算,不适用于大型表或者数据持久化的需求。
NDB:适用于所有节点都是数据节点且需要在多台机器上分布的高可用/高并发的大规模应用。它支持对数据的完全共享和高可用性,并且可以进行自动分片、自动故障转移等功能的支持。
ARCHIVE:适用于仅一次读取整个表的应用,例如日志、归档等。这种存储引擎适用于只需要保存数据而不需要频繁读写的场景,并将访问数据的时间换算为空间占用的减少,以提高速度。
InnoDB与MyISAM比较
InnoDB和MyISAM是MySQL中两个常用的存储引擎,它们的主要区别在于数据表的索引和事务处理方面。以下是InnoDB和MyISAM的比较:
事务:InnoDB支持事务处理,MyISAM不支持事务处理。这是因为InnoDB使用了行级锁定和MVCC(多版本并发控制)技术,而MyISAM只支持表级锁定。
锁机制:InnoDB采用行级锁定(ROW LOCKS)机制,MyISAM采用表级锁定(TABLE LOCKS)机制。这意味着,在高并发的环境下,InnoDB可以更好地处理读写并发,而MyISAM容易出现读写冲突的问题。
自动增量列:在InnoDB中,必须将自动增量列放置在主键上,而MyISAM则可以将自动增量列放置在任何除TEXT、BLOB等大字段外的列上。
索引:InnoDB的索引结构是B+树,其主键索引的叶子节点data域会存放数据,也就是聚簇索引(因此InnoDB要求每个表都必须要有主键)。MyISAM 也是使用B+树作为索引存储结构,但他的叶子节点data域存放的是数据的物理地址(非聚簇索引),即索引结构和真正的数据结构其实是分开存储的。
数据缓存:InnoDB通过自己的缓存机制进行数据管理,MyISAM则依赖于操作系统的缓存机制。因此,在高并发的环境下,InnoDB可以提供更出色的性能。
存储过程:InnoDB支持存储过程,可以更好地支持复杂的业务逻辑。MyISAM则不支持存储过程。
由此可见,InnoDB和MyISAM在事务处理、锁机制、索引结构、数据缓存等方面存在很大的区别, 以下是一些使用上述两个存储引擎的建议:
确定数据表类型:在创建数据表时,应该明确数据表的类型,如选择关系型数据库存储引擎,应该选择支持全文索引和事务处理引擎的存储引擎,如选择非关系型数据库存储引擎,应该选择支持高效并发访问和快速数据插入的存储引擎。
确定性能需求:如果数据表的性能需求较高,如需要支持全文索引、高并发访问和快速数据插入等,应该选择支持这些特性的存储引擎,如如果需要基本查询和插入操作的性能较高,可以选择MyISAM或InnoDB等基本存储引擎。
支持数据完整性检查:如果需要支持数据完整性检查的存储引擎,应该选择支持数据完整性检查的存储引擎,如选择MyISAM,因为MyISAM不支持数据完整性检查。
优化查询语句:如果查询语句中使用了全文索引或复杂的查询条件,应该选择支持这些特性的存储引擎,如选择InnoDB,因为InnoDB可以更好地支持全文索引和复杂的查询条件。
避免使用存储过程:如果需要支持存储过程,应该选择支持存储过程的存储引擎,如选择MyISAM,因为MyISAM不支持存储过程。
综合参考:如果需要支持事务处理、具有更出色的性能和更好的扩展性等要求,建议使用InnoDB;如果只需要简单的数据管理功能,可以使用MyISAM。
内存引擎MEMORY
然MYSQL也有可以基于内存操作的数据引擎Memory,为什么还需要和Redis配合使用呢?Memory为什么没有redis的应用广泛?下面不妨挖掘下MEMORY引擎的特点:
- MEMORY引擎的内存表默认使用的是hash索引(跟Redis/Memcached一样),hash索引最大的优势就是,等值查询和更新速度都很快,但范围查询和排序就不给力。
- MEMORY引擎也可以声明B+树索引,使其具备出色的范围查询能力,但是占用空间会变多。
- MEMORY引擎读写性能是InnoDB的几十倍,该速度还是远远逊色于Redis。
- Memory不支持行锁只支持表锁,因此Memory存储引擎在进行并发操作时会造成大量的阻塞;而redis采用的是nio方式,且redis数据结构更为简单(以KV为主,非表结构)。
- Memory存储引擎的所有数据都存储在内存当中,当数据库重启时(无论是否是异常重启还是正常的升级重启),由于其没有持久化机制,会导致内存当中的数据全部丢失,而redis有完善的数据持久化机制(RDB和AOF)
- Memory存储引擎的主从机制并不健壮!如果从库发生重启,则主库同步过来的所有update语句都执行失败,造成主备同步的停滞。如果数据库采用双M架构,那么在数据库重启之前,会向binlog中写入一条delete from table t ,这条binlog传到另一个库执行后会造成两个库的内存表数据全部丢失。这些情况都是难以避免的,无疑加大了维护成本。
综上而言,MEMORY和redis核心还是其场景功能不一样:前者是完全依赖内存做表管理,后者是专注于做分布式环境的数据缓存服务。