在写之前先整理一下mysql是如何工作的
图片引自王英英老师的 《mysql 8从入门到精通》(这不算是侵权吧)
MySQL客户端登陆后,MySQLD开始初始化。
- 首先检查用户权限(用户名密码是否符合登陆要求)–其中初始化的时候有一些参数比如查询缓存,日志记录模块如果开启,这也会一同开启,当然存储引擎也会一同开启。
- 初始化过后是链接管理模块,监听客户端命令,将命令转发给进(线)程管理模块,由进程管理模块将命令转发给用户模块—这时候用户模块检查该用户的权限–比如select,insert等权限,如果无权限则返回没有权限的提示,有权限则会进一步将命令转发给命令解释器去将命令下放到各个不同的小模块中,如果是select 查询,就启用查询优化器,如果优化器缓存中有已经存在的结果集就返回给用户,如果没有就分发给相应的模块进行处理。
- 当命令执行完毕后,控制权都会还给链接现成模块(因为要I/O输入/出)
以上如有不当之处还请评论区指出,我会第一时间修改。
接下来算是正题吧!!!
MySQL中最常用的两种存储引擎 myIsam、innodb,其他也会用到比如merge,memory
8.0将innodb作为默认存储引擎,我也是直接从8.0开始学的,我先总结一下innodb吧!
innodb存储引擎的特点
1,支持事务性操作,支持提交、回滚和 崩溃恢复能力–二进制日志和erro日志
对于innodb每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
2,支持外键约束以保证数据的一致性 ;
3,innodb专门为数据量大表而设计,CPU处理效率高(这点我还没体会到) ;
4,innodb支持表空间> 共享还是私有,这样生成的文件不一样, 私有空间.ibd,共享空间是.ibddata innodb 的数据文件中包含索引和数据;
5,innodb是聚集索引,索引结构为BTree,数据文件和(主键)索引绑在一起的, 先查询到主键,然后再通过主键查询到数据,但是主键不应该过大;
6,innodb使用缓冲池来缓存索引和索引行数据。设置越大,需要的磁盘I/O就越少访问表中的数据。
InnoDB, unlike MyISAM, uses a buffer pool to cache both indexes and
row data. The bigger you set this the less disk I/O is needed to
access data in tables. On a dedicated database server you may set this
parameter up to 80% of the machine physical memory size. Do not set it
too large, though, because competition of the physical memory may
cause paging in the operating system. Note that on 32bit systems you
might be limited to 2-3.5G of user level memory per process, so do not
set it too high.
6,
MyISAM存储引擎的特点
1,不支持事务和外键,但是插入和查询速度高;
2,数据和索引分开存储,表结构文件.frm 数据树即索引文件.myi,数据文件.myd ;
3,同样采用Btree存储结构,text和blob可以被索引,被索引的列值中可以出现Null;
Memory存储引擎的特点
1,索引为btree和hash;
2,以固定的长度记录数据,所以不支持blob和text;
3,被索引的列值中也可以出现Null;
4,表是共享的,因为memory表的内容被存放在内存中,当不需要memory时应该删除以免占用内存空间;
Merge存储引擎的特点
merge其实就是myisam的组合,一组myisam组合成merge,所以merge表本身没有数据,(创建merge表时只会创建两个较小的文件 .frm(数据结构)和.mrg(存放表的插入信息)
插入操作是通过insert_method完成的(first 和last来插入数据)
演示一下merge存储引擎–
mysql> create table one (id int primary key ,name varchar(128)) engine= myisam;
Query OK, 0 rows affected (0.01 sec)
mysql> create table two (id int primary key ,name varchar(128)) engine= myisam;
Query OK, 0 rows affected (0.01 sec)
mysql> create table three (id int primary key ,name varchar(128)) engine= merge union=(one,two) ins
ert_method=first;
Query OK, 0 rows affected (0.01 sec)
mrg文件存放哪两张表以及插入方式(first或者last)
mysql> insert into one values(1001,'jack'),(1002,'mary');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into three values(1003,'tom'),(1004,'gavin');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from three;
+------+-------+
| id | name |
+------+-------+
| 1001 | jack |
| 1002 | mary |
| 1003 | tom |
| 1004 | gavin |
+------+-------+
4 rows in set (0.00 sec)
mysql> insert into two values(1005,'sam'),(1006,'king');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from three;
+------+-------+
| id | name |
+------+-------+
| 1001 | jack |
| 1002 | mary |
| 1003 | tom |
| 1004 | gavin |
| 1005 | sam |
| 1006 | king |
+------+-------+
6 rows in set (0.00 sec)
mysql> select * from one ;
+------+-------+
| id | name |
+------+-------+
| 1001 | jack |
| 1002 | mary |
| 1003 | tom |
| 1004 | gavin |
+------+-------+
4 rows in set (0.00 sec)
mysql> select * from two ;
+------+------+
| id | name |
+------+------+
| 1005 | sam |
| 1006 | king |
+------+------+
2 rows in set (0.00 sec)
mysql>
当我们查询one 表和two内容时,我们发现插入three(merge引擎)的数据跑到了one表中,因为插入时制定了insert_method=first;当没有指定insert_method时向three表插入数据就会报错,因为系统不知道将数据插入到哪里;