目录
存储引擎
概念
类型
示例
数据库文件
MylSAM
.frm
.MYD
.MYI
InnoDB
.frm
.ibd
.opt
查看指定表的存储引擎类型
查看系统支持的存储引擎
修改存储引擎
通过配置文件指定存储引擎
使用alter修改
创建表的同时指定存储引擎
使用set命令临时指定存储引擎
比较MyISAM和InnoDB
写入速度比较
插入数据
tm表的存储过程
ti表的存储过程
测试
查询数据速度比较
没有索引的列
有索引的列
总结
存储引擎
概念
数据库存储引擎是数据库底层组件,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据操作。
不同的存储引擎提供不同的存储机制、索引功能、锁定水平等功能,使用不同的存储引擎还可以获得特定的功能。
存储引擎是针对数据表的,在同一个数据库中,不同的表可以使用不同的存储引擎
类型
功能 | MylSAM | MEMORY | InnoDB |
存储限制 | 256TB | 内存 | 64TB |
支持事务 | No | No | Yes |
支持全文索引 | Yes | No | No |
支持树索引 | Yes | Yes | Yes |
支持哈希索引 | No | Yes | No |
支持数据缓存 | No | N/A | Yes |
支持外键 | No | No | Yes |
InnoDB:行级锁定(select * from tableName where name = 'tom' for update;)锁定该表的更新功能
MyISAM:表级锁定
示例
数据库文件
MylSAM
cd到mysql存放数据的data目录下的mysql目录
ls一下可以看到很多.frm、.MYD、MYI文件,这些文件都是MyISAM存储引擎生成的
[root@localhost data]# cd /usr/local/mysql/data/mysql
[root@localhost mysql]# ls
user.frm
user.MYD
user.MYI
-
.frm
- 数据表结构,比如表有多少列,每个列的名字
-
.MYD
- 存放表中数据
-
.MYI
- 专门存放索引的信息的文件
InnoDB
先登录进数据库,然后创建一个数据库和表,再退出数据库
[root@localhost mysql]# mysql -uroot -p
mysql> create database auth;
mysql> use auth
mysql> create table users(id int(10), name char(20));
mysql> quit
退出后,在当前位置cd到上一级目录下,也就是/usr/local/mysql/data目录下
ls一下,可以看到一个和刚刚创建的数据库相同名称的目录,进入该目录
就可以看到,在auth的库中,一共有三个文件,这些文件都是由InnoDB生成的,这里每个表都对应了两个文件,分别是:.frm和.ibd文件
-
.frm
- 存放数据表的元数据
-
.ibd
- 和MyISAM的.MYD文件类似,存放数据表中的数据
-
.opt
- 存放MySQL的配置信息
[root@localhost mysql]# cd ..
[root@localhost data]# ls
auth
[root@localhost data]# cd auth
[root@localhost auth]# ls
db.opt users.frm users.ibd
此时我们再次登录进数据库然后在auth库中创建第二个表
[root@localhost auth]# mysql -uroot -p
mysql> use auth
mysql> create table users001(id int(10), name char(20));
mysql> quit
再退出数据库,ls一下,可以看到又多了两个文件,而不是像第一次创建表时,多了三个文件
[root@localhost auth]# ls
db.opt users001.frm users001.ibd users.frm users.ibd
其实opt文件存储的是该数据库的配置信息,编码规则等信息,该库中的所有表共用该.opt文件
查看指定表的存储引擎类型
登录进MySQL,使用下方代码块内的show命令查看指定库指定表的状态信息
- Engine: InnoDB:该表使用的存储引擎
- Create_time:创建该表的时间
- Collation: utf8_general_ci:校对字符集
[root@localhost auth]# mysql -uroot -p
mysql> show table status from auth where name = 'users'\G;
*************************** 1. row ***************************
Name: users
Engine: InnoDB
# ...
Create_time: 2024-07-29 09:21:14
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
# 省略其他内容
查看系统支持的存储引擎
mysql> show engines;
修改存储引擎
通过配置文件指定存储引擎
在[mysqld]单元内,修改存储引擎类型
[mysqld]
default-storage-engine=MYISAM
使用alter修改
进入要操作的数据库,通过alter命令修改表结构,来修改users表的存储引擎
修改完后,再使用show命令查询,可以看到存储引擎已经变成MyISAM
mysql> use auth
mysql> alter table users engine=myisam;
mysql> show table status from auth where name = 'users'\G;
*************************** 1. row ***************************
Name: users
Engine: MyISAM
# 省略其他内容
mysql> quit
此时再退出数据库,ls查看当前目录下的文件,可以看到由于修改了存储引擎,又多出了两个文件
假如在一个表中设有事务相关的指令,如果此时把存储引擎从InnoDB改为MyISAM,由于MyISAM不支持事务,所以可能会导致该表出现错误无法使用
[root@localhost auth]# ls
db.opt users001.frm users001.ibd users.frm users.MYD users.MYI
创建表的同时指定存储引擎
登录MySQL,进入auth数据库,创建表时在末尾使用engine选项指定存储引擎
创建完后,再使用show命令查看该表的状态信息,可以看到存储引擎是MyISAM
[root@localhost auth]# mysql -uroot -p
mysql> use auth
mysql> create table test (id int(10), name char(20)) engine=myisam;
mysql> show table status from auth where name = 'test'\G;
*************************** 1. row ***************************
Name: test
Engine: MyISAM
# ...
使用set命令临时指定存储引擎
使用set命令临时指定默认存储引擎为MyISAM
新创建的表将默认使用 MyISAM 存储引擎,但在新的会话中或者重新启动 MySQL 后,这个设置会被重置
mysql> set default_storage_engine=myisam;
mysql> show table status from auth where name = 't2'\G;
*************************** 1. row ***************************
Name: t2
Engine: MyISAM
比较MyISAM和InnoDB
写入速度比较
比较处理数据的速度
创建用于比较两个存储引擎性能的数据库,然后进入该数据库
分别创建两个表,tm表示测试myisam的表,ti表示测试innodb的表
mysql> create database test;
mysql> use test
mysql> create table tm(id int(20) primary key auto_increment,name char(30)) engine=myisam;
mysql> create table ti(id int(20) primary key auto_increment,name char(30)) engine=innodb;
插入数据
这里我们使用存储过程插入一千万行数据,来比较两个存储引擎的存储效率
因为要在存储过程中写SQL语句,需要加分号(;)结尾,但是在编写的时候加分号结尾就直接退出了整个存储过程
所以需要先修改SQL语句的结束标识,才能正常编写存储过程的命令
mysql> delimiter $
tm表的存储过程
修改完结束标识符后,直接在mysql中输入以下语句
向表tm中插入从tom1到 tom10000000 这一千万条数据
create procedure insertm()
begin
set @i=1;
while @i<=10000000
do
insert into tm (name) values (concat("tom", @i));
set @i=@i+1;
end while;
end
$
ti表的存储过程
向表ti中插入从tom1到 tom10000000 这一千万条数据
create procedure inserti()
begin
set @i=1;
while @i<=10000000
do
insert into ti (name) values (concat("jerry", @i));
set @i=@i+1;
end while;
end
$
测试
先把结束标识符改回分号(;)以便进行下一步操作
使用 call 命令调用存储过程,然后等待执行完毕
mysql> delimiter ;
mysql> call insertm;
# 等待执行完毕...
Query OK, 0 rows affected (2 min 30.66 sec) # 用时2分30.66秒
mysql> call inserti;
# 等待执行完毕...
Query OK, 0 rows affected (22 min 9.11 sec) # 用时22分9.11秒
由此可见,MyISAM的写入速度比InnoDB更快
查询数据速度比较
没有索引的列
mysql> select * from tm where name > "tom100" and name < "tom10000000";
+---------+------------+
| id | name |
+---------+------------+
| 1000 | tom1000 |
| 10000 | tom10000 |
| 100000 | tom100000 |
| 1000000 | tom1000000 |
+---------+------------+
4 rows in set (1.02 sec)
mysql> select * from ti where name > "jerry100" and name < "jerry10000000";
+---------+--------------+
| id | name |
+---------+--------------+
| 1000 | jerry1000 |
| 10000 | jerry10000 |
| 100000 | jerry100000 |
| 1000000 | jerry1000000 |
+---------+--------------+
4 rows in set (2.12 sec)
有索引的列
mysql> select * from tm where id > 10 and id < 999999;
999988 rows in set (1.42 sec)
mysql> select * from ti where id > 10 and id < 999999;
999988 rows in set (0.40 sec)
总结
- 写入速度:MyISAM更快
- 读取速度(无索引):MyISAM更快
- 读取速度(有索引):InnoDB更快