MyISAM:不支持事务、外键约束,只支持表级锁定,适合单独的查询或插入操作,读写并发能力较弱,支持全文索引,资源占用较小,数据文件(.MYD)和索引文件(.MYI)是分开存储的。适用于不需要事务处理,单独的查询或者插入数据的业务场景
InnoDB:支持事务、外键约束,支持行级锁定(在全表扫描时仍然会表级锁定),读写并发能力较好,支持全文索引(5.5版本以后的),缓存能力较好可以减少磁盘IO的压力,数据文件也是索引文件。适用于需要事务的支持,一致性要求较高,数据会频繁更新,高并发读写的业务场景
静态(固定长度)表:静态表是默认的存储格式。静态表中的字段都是非可变字段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多。固定长度10存储非常迅速,容器缓存,故障之后容易恢复id(5) char(10)000000001
动态表:动态表包含可变字段(varchar),记录不是固定长度的,这样存储的优点是占用空间较少,但是频繁的更新、删除记录会产生碎片,需要定期执行 OPTIMIZE TABLE 语句或 myisamchk -r 命令来改善性能,并且出现故障的时候恢复相对比较困难
压缩表:压缩表由 myisamchk 工具创建,占据非常小的空间,因为每条记录都是被单独压缩的,所以只有非常小的访问开支
公司业务不需要事务的支持
单方面读取或写入数据比较多的业务
MyISAM存储引擎数据读写都比较频繁场景不适合
使用读写并发访问相对较低的业务
数据修改相对较少的业务
对数据业务一致性要求不是非常高的业务
服务器硬件资源相对比较差
总结:MyIsam:适合于单方向的任务场景、同时并发量不高、对于事务要求不高的场景
支持事务,支持4个事务隔离级别
MySQL从5.5.5版本开始,默认的存储引擎为InnoDB
读写阻塞与事务隔离级别相关
能非常高效的缓存索引和数据
表与主键以簇的方式存储
支持分区、表空间,类似oracle数据库
支持外键约束,5.5前不支持全文索引,5.5后支持全文索引
对硬件资源要求还是比较高的场合
行级锁定,但是全表扫描仍然会是表级锁定(update table set a=1 where user like ‘%zhang%’;)
InnoDB 中不保存表的行数,如select count() from table;时,InnoDB需要扫描一遍整个表来计算有多少行,但是MyISAM 只要简单的读出保存好的行数即可。需要注意的是,当count()语句包含where条件时 MyISAM 也需要扫描整个表
对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立组合索引
清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表
show engines;
例:mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
| ------ | ------- | ------- | ------------ | ---- | ---------- |
| | | | | | |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| ------------------ | ------- | ------------------------------------------------------------ | ---- | ---- | ---- |
| | | | | | |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| ---------- | ---- | ------------------------------------- | ---- | ---- | ---- |
| | | | | | |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| ------ | ---- | --------------------------------------------------------- | ---- | ---- | ---- |
| | | | | | |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| --------- | ---- | ------------------------------------------------------------ | ---- | ---- | ---- |
| | | | | | |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| ------ | ---- | --------------------- | ---- | ---- | ---- |
| | | | | | |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ---- | ---- | ------------------ | ---- | ---- | ---- |
| | | | | | |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| ------- | ---- | ---------------------- | ---- | ---- | ---- |
| | | | | | |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| ------------------ | ---- | ------------------ | ---- | ---- | ---- |
| | | | | | |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| --------- | ---- | ------------------------------ | ---- | ---- | ---- |
| | | | | | |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
方法1:show table status from 库名 where name='表名'\G
方法2:use 库名;
show create table 表名;
例:mysql> use tour;
Database changed
mysql> show create table moon;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| moon | CREATE TABLE "moon" (
"id" int(11) DEFAULT NULL,
"name" char(4) DEFAULT NULL,
"age" int(11) DEFAULT NULL,
"sex" char(2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
① 通过 alter table 修改
use 库名;
alter table 表名 engine=MyISAM;
② 通过修改 /etc/my.cnf 配置文件,指定默认存储引擎并重启服务
vim /etc/my.cnf
......
[mysqld]
......
default-storage-engine=INNODB
systemctl restart mysql.service
③ 通过 create table 创建表时指定存储引擎
use 库名;
create table 表名(字段1 数据类型,...) engine=MyISAM;
MyISAM :默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且不支持外键,如果执行大量的select,insert MyISAM比较适合
InnoDB :支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。注: 在MySQL 5.5之前的版本中,默认的搜索引擎是MyISAM,从MySQL 5.5之后的版本中,
默认的搜索引擎变更为InnoDB
delete from t1 where id=1;
delete from t1 where name='aaa';
delete from t1 where age=23;
create table t1(id int primary key, name char(3), age int);
insert into t1 values(1,'aaa',22);
insert into t1 values(2,'bbb',23);
insert into t1 values(3,'aaa',24);
insert into t1 values(4,'bbb',25);
insert into t1 values(5,'ccc',26);
insert into t1 values(6,'zzz',27);
session 1 #分主机1
begin;
delete from t1 where id=5;
session 2 #分主机2
begin;
select * from t1 where id=1 for update;
session 1 #分主机1
delete from t1 where id=1; #死锁发生
session 2 #分主机2
update t1 set name='abc' where id=5; #死锁发生