InnoDB是MySQL默认的存储引擎,属于事务型存储引擎,从MySQL 5.5版本开始就成为官方默认选择的存储引擎,被广泛应用在各种业务系统中。它设计的核心目标是兼顾高可靠性和高性能,能够支持大规模的高并发读写操作,同时保证数据的完整性和一致性。
InnoDB的核心特性
1. 支持事务和ACID特性
InnoDB完全支持事务的ACID特性,也就是原子性、一致性、隔离性、持久性。所有的增删改操作都可以放在事务中执行,要么全部成功要么全部回滚,避免数据出现不一致的情况。下面是一段简单的事务操作示例:
-- 开启事务 START TRANSACTION; -- 执行扣减用户余额操作 UPDATE user_account SET balance = balance - 100 WHERE user_id = 1; -- 执行增加商户余额操作 UPDATE merchant_account SET balance = balance + 100 WHERE merchant_id = 1; -- 提交事务,如果中间出现异常可以执行ROLLBACK回滚 COMMIT;
2. 支持行级锁
InnoDB的锁粒度是行级锁,和表级锁相比,行级锁的并发性能更高。当多个事务同时操作不同的行数据时,不会产生锁冲突,只有在操作同一行数据的时候才需要等待锁释放。行级锁的实现依赖于索引,如果执行的SQL语句没有使用索引,InnoDB会退化为表级锁。
3. 支持外键约束
InnoDB是唯一支持外键约束的MySQL常用存储引擎,外键可以保证关联表之间的数据一致性。比如订单表的用户ID必须存在于用户表中,就可以通过外键来约束。下面是创建带外键的表的示例:
-- 创建用户表
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL
) ENGINE=InnoDB;
-- 创建订单表,user_id关联用户表的id
CREATE TABLE order_info (
id INT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(50) NOT NULL,
user_id INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES user(id)
) ENGINE=InnoDB;
4. 聚簇索引存储
InnoDB使用聚簇索引来组织数据,表的数据和主键索引是存储在一起的,主键索引的叶子节点直接存储了整行数据。如果表没有定义主键,InnoDB会选择一个唯一的非空索引作为主键,如果没有这样的索引,会隐式生成一个6字节的row_id作为主键。
InnoDB和MyISAM的对比
MyISAM是MySQL早期的默认存储引擎,和InnoDB有很多差异,具体对比如下:
| 对比项 | InnoDB | MyISAM |
|---|---|---|
| 事务支持 | 支持 | 不支持 |
| 锁粒度 | 行级锁 | 表级锁 |
| 外键支持 | 支持 | 不支持 |
| 全文索引 | 5.6版本后支持 | 支持 |
| 崩溃恢复 | 支持,可靠性高 | 不支持,崩溃后可能丢失数据 |
| 适用场景 | 高并发、事务型业务 | 读多写少、不需要事务的场景 |
InnoDB的适用场景
InnoDB几乎适用于所有需要保证数据一致性和高并发的业务场景,常见的有:
- 电商系统的订单、支付、用户账户相关表,需要事务保证资金和数据一致性
- 社交平台的用户动态、评论表,高并发读写场景需要行级锁提升性能
- 企业级业务系统的核心业务表,需要外键约束保证关联数据完整性
- 需要频繁进行增删改操作的业务表,InnoDB的写性能经过优化后表现稳定
如何查看和修改表的存储引擎为InnoDB
如果需要查看某张表的存储引擎,可以执行下面的SQL语句:
-- 查看表的存储引擎,table_schema是数据库名,table_name是表名 SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE table_schema = 'test_db' AND table_name = 'user';
如果需要修改已有表的存储引擎为InnoDB,可以执行下面的语句:
ALTER TABLE user ENGINE = InnoDB;
如果是新建表的时候指定使用InnoDB存储引擎,只需要在建表语句最后加上ENGINE=InnoDB即可,如前面创建用户表的示例所示。