存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可被称为表类型(一个数据库中的不同表可以有不同的存储引擎)
查看当前数据库支持的存储引擎: show engines;
在创建表时,指定存储引擎
create table 表名 ( 字段名 字段类型 [comment 字段注释] ) engine=innodb [comment 表注释];
InnoDB是一种兼顾高可靠性和高性能的通用存储引擎,在 MySQL 5.5 之后,InnoDB是默认的 MySQL 存储引擎
InnoDB存储引擎涉及的表文件:
innodb_file_per_table
控制到底多张表共享一个表空间文件还是每张表都对应一个表空间,默认是打开的show variables like 'innodb_file_per_table';
MyISAM是MySQL早期的默认存储引擎
MyISAM存储引擎涉及的表文件:
Memory引擎的表数据时存储在内存中的,由于受到硬件问题、或断电问题的影响,只能将这些表作为临时表或缓存使用
Memory存储引擎涉及的表文件:
特点 | InnoDB | MyISAM | Memory |
---|---|---|---|
存储限制 | 64TB | 有 | 有 |
事务安全 | 支持 | —— | —— |
锁机制 | 行锁 | 表锁 | 表锁 |
B+tree索引 | 支持 | 支持 | 支持 |
Hash索引 | —— | —— | 支持 |
全文索引 | 支持(5.6版本之后) | 支持 | —— |
空间使用 | 高 | 低 | N/A |
内存使用 | 高 | 低 | 中等 |
批量插入速度 | 低 | 高 | 高 |
支持外键 | 支持 | —— | —— |
在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合
索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引
MySQL的索引是在存储引擎层面实现的,不同的存储引擎有不同的结构,主要包含以下几种:
索引结构 | 说明 |
---|---|
B+Tree索引 | 最常见的索引类型,大部分引擎都支持B+Tree索引 |
Hash索引 | 底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询 |
R-Tree(空间索引) | 空间索引是MyISM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少 |
Full-text(全文索引) | 是一种通过建立倒排索引,快速匹配文档的方式.类似于Lucene,Solr,ES |
索引 | InnoDB | MyISAM | Memory |
---|---|---|---|
B+Tree索引 | 支持 | 支持 | 支持 |
Hash索引 | 不支持 | 不支持 | 支持 |
R-Tree索引 | 不支持 | 支持 | 不支持 |
Full-Text | 5.6版本之后支持 | 支持 | 不支持 |
索引分类 | 含义 | 特点 | 关键字 |
---|---|---|---|
主键索引 | 针对表中主键创建的索引 | 默认自动创建,只能有一个 | primary |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | unique |
常规索引 | 快速定位特定数据 | 可以有多个 | |
全文索引 | 全文索引查找的是文本中的关键词,而不是比较索引中的值 | 可以有多个 | fulltext |
在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:
分类 | 含义 | 特点 |
---|---|---|
聚集索引(Clustered Index) | 将数据存储与索引放到了一块,索引结构的叶子结点保存了行数据 | 必须有,而且只有一个 |
二级索引/辅助索引(Secondary Index) | 将数据和索引分开存储,索引结构的叶子结点关联的是对应的主键 | 可以存在多个 |
聚集索引选取规则:
一个索引可以是单列索引,也可以是联合索引/组合索引(多列)
索引操作 | SQL语法 |
---|---|
创建索引 | create [unique | fulltext] index index_name on table_name (index_col_name,…); |
查看索引 | show index from table_name; |
删除索引 | drop index index_name on table_name; |
查看SQL执行频率
MySQL客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令,可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次:
-- 7个下划线 show global status like 'Com_______'
慢查询日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志
show variables like 'slow_query_log';
MySQL的慢查询日志默认没有开启,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
vi /etc/my.cnf
# 开启MySQL慢查询开关 slow_query_log=1 # 设置慢查询的时间为2秒;SQL语句执行时间超过2秒,就会视为慢查询 long_query_time=2
systemctl restart mysqld
慢查询日志文件存储在 /var/lib/mysql/localhost-slow.log
profile详情
show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪里去了
select @@profiling;
select @@profiling;
set profiling=1;
执行一系列的业务SQL的操作,然后通过如下指令查看指令的执行耗时:
-- 查看每一条SQL的耗时基本情况 show profiles; -- 查看指定query_id的SQL语句各个阶段的耗时情况 show profile for query query_id; -- 查看指定query_id的SQL语句CPU的使用情况 show profile cpu for query query_id;
explain执行计划
explain或者desc命令获取MySQL如何执行select语句的信息,包括在select语句执行过程中表如何连接和连接的顺序
-- 直接在select语句之前加上关键字explain或者desc explain select 字段列表 from 表名 where 条件;
explain各字段 | 说明 |
---|---|
id | 表示查询中执行select子句或者是操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行) |
select_type | 表示select的类型,常见的取值有simple(简单表:不使用表连接或者子查询);primary(主查询:外层的查询);union(union中的第二个或者后面的查询语句);subquery(select/where之后包含了子查询)等 |
type | 表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、 index、all(全表扫描) |
possible_key | 显示可能应用在这张表上的索引,一个或多个 |
key | 实际使用的索引,如果为NULL,则没有使用索引 |
key_len | 表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好 |
rows | MySQL认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值,可能并不总是准确的 |
filtered | 表示返回结果的行数占需读取行数的百分比,filtered的值越大越好 |
SQL提示:是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优化操作的目的
explain select * from tb_user use index(idx_user_pro) where profession='Java'
explain select * from tb_user ignore index(idx_user_pro) where profession='Java'
explain select * from tb_user force index(idx_user_pro) where profession='Java'
前缀索引:当字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率.此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率
create index idx_xxx on table_name(column(n))
select count(distinct email)/count(*) from tb_user;
select count(distinct substring(email,1,5)/count(*) from tb_user;
insert into 表名 values(1,'Tom'),(2,'Cat'),(3,'Jerry');
start transaction; insert into 表名 values(1,'Tom'),(2,'Cat'),(3,'Jerry'); insert into 表名 values(4,'Tom'),(5,'Cat'),(6,'Jerry'); insert into 表名 values(7,'Tom'),(8,'Cat'),(9,'Jerry'); commit;
如果需要一次性插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入
--local-infile
mysql --local-infile -u root -p
select @@local_infile; set global local_infile=1;
load data local infile '/opt/resources/load_user_100w_sort.txt' into table tb_user fields terminated by ',' lines terminated by '\n';
数据组织方式:在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)
主键设计原则
① Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高
② Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫FileSort排序
-- 根据age和phone字段进行排序:一个升序,一个降序 explain select id,age,phone from tb_user order by age asc,phone desc; -- 根据age和phone字段进行排序(默认都是升序) explain select id,age,phone from tb_user order by age,phone; -- 查看排序缓冲区大小 show variables like 'sort_buffer_size';
一个常见又非常头疼的问题就是 limit 2000000,10
,此时需要MySQL排序前2000010记录,仅仅返回2000000 - 2000010 的记录,其他记录丢弃,查询排序的代价非常大
优化思路: 一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化
explain select * from tb_sku t,(select id from tb_sku order by id limit 2000000,10) a where t.id=a.id;
count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数不是NULL,累计值就加1,否则不加,最后返回累计值
按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(*),所以尽量使用 count(*)
InnoDB的行锁是针对索引加的锁,不是针对记录加的锁 ,并且该索引不能失效,否则会从行锁升级为表锁
视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的
通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上
视图操作分类 | 具体操作内容 | SQL语法 |
---|---|---|
创建 | 创建视图 | create [or replace] view 视图名称(列名列表) as select语句 [with [ cascaded | local ] check option] |
查询 | 查看视图结构 | show create view 视图名称; |
查看视图数据 | select * from 视图名称; | |
修改 | 修改视图 | create or replace view 视图名称(列名列表) as select语句 [with [ cascaded | local ] check option] |
修改视图 | alter view 视图名称(列名列表) as select语句 [with [ cascaded | local ] check option] | |
删除 | 删除视图 | drop view [if exists] 视图名称 [,视图名称]…; |
视图的检查选项:当使用WITH CHECK OPTION子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如 插入,更新,删除,以使其符合视图的定义。MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项:CASCADED 和 LOCAL ,默认值为 CASCADED
要使视图可更新,视图中的行与基础表中的行之间必须存在一对一的关系。如果视图包含以下任何一项,则该视图不可更新:
视图的作用:
存储过程是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用
存储过程特点
-- 创建存储过程语法 create procedure 存储过程名称([参数列表]) begin -- SQL语句集合 end; -- 调用存储过程 call 名称([参数列表]); -- 查看指定数据库的存储过程及状态信息 select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_SCHEMA='xxx'; -- 查询某个存储过程的定义 show create procedure 存储过程名称; -- 删除指定的存储过程 drop procedure [if exists] 存储过程名称;
注意: 在命令行中,执行创建存储过程的SQL时,需要通过关键字 delimiter
指定SQL语句的结束符
系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION,默认);
操作分类 | 具体内容 | SQL语法 |
---|---|---|
查看系统变量 | 查看所有系统变量 | show [ session | global ] variables; |
通过模糊匹配方式查找变量 | show [ session | global ] variables like '……'; | |
查看指定变量的值 | select @@[ session. | |
设置系统变量 | 设置系统变量方式一 | set [ session | global ] 系统变量名 = 值; |
设置系统变量方式二 | set [ session | global ] 系统变量名 := 值; | |
设置系统变量方式三 | set @@[ session. | global. ]系统变量名 = 值; |
注意
用户定义变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@变量名”使用就可以。其作用域为当前连接
操作分类 | SQL语法 |
---|---|
赋值 | set @变量名 = 变量值 [, @变量名 = 变量值]; |
set @变量名 := 变量值 [, @变量名 := 变量值]; | |
select @变量名 := 变量值 [, @变量名 := 变量值]; | |
select 字段名 into @变量名 from 表名; | |
使用 | select @变量名; |
局部变量是根据需要定义的在局部生效的变量,访问之前,需要DECLARE声明。可用作存储过程内的局部变量和输入参数,局部变量的范围是在其内声明的BEGIN ... END块
操作分类 | SQL语法 |
---|---|
声明 | declare 变量名 变量类型 [default ……]; |
赋值 | set 变量名 = 值; |
set 变量名 := 值; | |
select 字段名 into 变量名 from 表名; |
形参类型 | 说明 |
---|---|
in | 默认值;该类参数作为输入,也就是需要调用时传入值 |
out | 该类参数作为输出,也就是该参数可以作为返回值 |
inout | 既可以作为输入参数,也可以作为输出参数 |
if 条件1 then …… elseif 条件2 then …… else …… end if;
-- 案例一 create procedure p1(in score int, out result varchar(10)) begin if score >= 85 then set result := '优秀'; elseif score >= 60 then set result := '及格'; else set result := '不及格'; end if; end; call p1(98, @result); select @result; -- 案例二:将传入的200分制的分数,进行换算,换算成百分比,然后返回分数 create procedure p2(inout score double) begin set score := score * 0.5; end; set @score = 70; call p2(@score); select @score;
case case_value when when_value1 then statement_list1 [when when_value2 then statement_list2] [else statement_list] end case; -- 语法二 case when search_condition1 then statement_list1 [when search_condition2 then statement_list2] [else statement_list] end case;
-- 根据传入的月份,判定月份所属的季节 create procedure p3(in month int) begin declare result varchar(10); case when month >= 1 and month <= 3 then set result := '第一季度'; when month >= 4 and month <= 6 then set result := '第二季度'; when month >= 7 and month <= 9 then set result := '第三季度'; when month >= 10 and month <= 12 then set result := '第四季度'; else set result := '非法参数'; end case; select concat('您输入的月份为:', month, ',所属的季度为:', result); end; call p3(7);
-- while 循环是有条件的循环控制语句。满足条件后,再执行循环体中的SQL语句。具体语法为: while 条件 do SQL逻辑 end while;
-- 计算从1累加到n的值,n为传入的参数值 create procedure p4(in n int) begin declare total int default 0; while n > 0 do set total := total + n; set n := n - 1; end while; select total; end; call p5(100);
-- repeat是有条件的循环控制语句,当满足条件的时候退出循环 -- 先执行一次逻辑,然后判断逻辑是否满足;如果满足,则退出;如果不满足,则继续下一次循环 repeat SQL逻辑 until 条件 end repeat;
-- 计算从1累加到n的值,n为传入的参数值 create procedure p5(in n int) begin declare total int default 0; repeat set total := total + n; set n := n - 1; until n <= 0 end repeat; select total; end; call p5(100);
Loop实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用来实现简单的死循环.Loop可以配合以下两个语句使用:
[begin_label:] loop SQL逻辑 end loop [end_label]; leave lable; -- 退出指定标记的循环体 iterate label; -- 直接进入下一次循环
-- 计算从1累加到n的值,n为传入的参数值 create procedure p6(in n int) begin declare total int default 0; sum:loop if n <= 0 then leave sum; end if; set total := total + n; set n := n - 1; end loop sum; select total; end; call p6(100); -- 计算从1到n之间的偶数累加的值,n为传入的参数值 create procedure p7(in n int) begin declare total int default 0; sum: loop if n <= 0 then leave sum; end if; if n % 2 = 1 then set n := n - 1; iterate sum; end if; set total := total + n; set n := n - 1; end loop sum; select total; end; call p7(100);
游标(CURSOR)是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、OPEN、FETCH 和 CLOSE,其语法分别如下
操作分类 | 说明 |
---|---|
声明游标 | declare 游标名称 cursor for 查询语句; |
打开游标 | open 游标名称; |
获取游标记录 | fetch 游标名称 into 变量[,变量]; |
关闭游标 | close 游标名称; |
游标使用逻辑流程:
条件处理程序(Handler)可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。具体语法为:
declare handler_action handler for condition_value [,condition_value] statement;
handler_action
condition_vlaue
MySQL错误状态码
-- 根据传入的参数uage,来查询用户表tb_user中,所有用户年龄小于等于uage的用户姓名name和专业profession -- 并将用户的姓名和专业插入到新创建的表中(id,name,profession)中 create procedure p8(in uage int) begin declare uname varchar(100); declare upro varchar(100); declare u_cursor cursor for select name, profession from tb_user where age <= uage; declare exit handler for SQLSTATE '02000' close u_cursor; -- declare exit handler for not found close u_cursor; drop table if exists tb_user_pro; create table tb_user_pro( id int primary key auto_increment, name varchar(100), profession varchar(100) ); open u_cursor; while true do fetch u_cursor into uname,upro; insert into tb_user_pro vlaues(null, uname, upro); end while; close u_cursor; end; call p8(30);
存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的。具体语法如下:
create function 存储函数名称([参数列表]) returns type [characteristic] begin SQL语句 return ...; end;
characteristic说明
create function fun1(n int) returns int deterministic begin declare total int default 0; while n > 0 do set total := total + n; set n := n - 1; end while; return total; end; select fun1(100);
触发器是与表有关的数据库对象,指在 insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性, 日志记录, 数据校验等操作
使用别名 OLD
和 NEW
来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发
触发器类型 | new和old |
---|---|
insert型触发器 | new表示将要或者已经新增的数据 |
update型触发器 | old表示修改之前的数据,new表示将要或已经修改后的数据 |
delete型触发器 | old表示将要或者已经删除的数据 |
-- 创建触发器 create trigger trigger_name before/after insert/update/delete on tbl_name for each row -- 行级触发器 begin trigger_stmt; end; -- 查看所有的触发器 show triggers; -- 删除触发器 drop trigger [schema_name.]trigger_name; -- 如果没有指定schema_name,默认为当前数据库
create trigger tb_user_insert_trigger after insert on tb_user for each row begin insert into user_logs(id, operation, operate_name, operate_id, operate_params) values (null, 'insert', now(), new.id, concat('插入的数据内容为:id=', new.id, ',name=', new.name, 'phone=', new.phone)); end;
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂
MySQL中的锁,按照锁的粒度分,分为以下三类:
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞
其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性
数据库中加全局锁,是一个比较重的操作,存在以下问题:
-- 加锁 flush tables with read lock; -- 释放锁 unlock tables; -- 在cmd中输入备份命令 mysqldump -uroot -p123456 数据库名 > 数据库备份名.sql
在InnoDB引擎中,我们可以在备份时加上参数 --single-transaction 参数来完成不加锁的一致性数据备份
mysqldump --single-transaction -uroot -p123456 数据库名 > 数据库备份名.sql
表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中
\[表级锁分类 \begin{cases} \text{表锁} \begin{cases} \text{表共享读锁(read lock)}\\ \text{表独占写锁(write lock)} \end{cases} \\ \text{元数据锁(meta data lock,MDL)} \\ \text{意向锁} \\ \end{cases} \]表锁语法
元数据锁
MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上。MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作
在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作的时候,加MDL写锁(排他)
对应SQL | 锁类型 | 说明 |
---|---|---|
lock tables XXX read/write | shared_read_only 或 shared_no_read_write | |
select 、select ... lock in share mode | shared_read | 与shared_read、shared_write兼容,与exclusive互斥 |
insert、update、delete、select ... for update | shared_write | 与shared_read、shared_write兼容,与exclusive互斥 |
alter table ... | exclusive | 与其他的MDL都互斥 |
查看元数据锁
select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;
意向锁:为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查
查看意向锁及行锁的加锁情况:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中
InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。对于行级锁,主要分为以下三类:
InnoDB实现了以下两种类型的行锁:
当前锁类型/请求锁类型 | S(共享锁) | X(排它锁) |
---|---|---|
S(共享锁) | 兼容 | 冲突 |
X(排它锁) | 冲突 | 冲突 |
SQL | 行锁类型 | 说明 |
---|---|---|
INSERT ... | 排他锁 | 自动加锁 |
UPDATE ... | 排他锁 | 自动加锁 |
DELETE ... | 排他锁 | 自动加锁 |
SELECT(正常) | 不加任何锁 | |
SELECT ... LOCK IN SHARE MODE | 共享锁 | 需要手动在SELECT之后加LOCK IN SHARE MODE |
SELECT ... FOR UPDATE | 排他锁 | 需要手动在SELECT之后加FOR UPDATE |
默认情况下,InnoDB在 REPEATABLE READ事务隔离级别运行,InnoDB使用 next-key 锁进行搜索和索引扫描,以防止幻读。
查看意向锁及行锁的加锁情况:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
默认情况下,InnoDB在 REPEATABLE READ事务隔离级别运行,InnoDB使用 next-key 锁进行搜索和索引扫描,以防止幻读
注意:间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁
MySQL5.5版本开始,默认使用InnoDB存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发中使用非常广泛。下面是InnoDB架构图,左侧为内存结构,右侧为磁盘结构
内存架构
磁盘结构
create tablespace xxx add datafile 'file_name' engine=engine_name;
create table xxx ... tablespace ts_name;
后台线程
IO线程类型 | 默认个数 | 职责 |
---|---|---|
Read thread | 4 | 负责读操作 |
Write thread | 4 | 负责写操作 |
Log thread | 1 | 负责将日志缓冲区刷新到磁盘 |
Insert buffer thread | 1 | 负责将写缓冲区内容刷新到磁盘 |
redo log解决事务的持久性
undo log解决事务的原子性:回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制)
MySQL数据库安装完成后,自带了四个数据库,具体作用如下:
数据库 | 含义 |
---|---|
mysql | 存储MySQL服务器正常运行所需要的各种信息(时区/主从/用户/权限等) |
information_schema | 提供了访问数据库元数据的各种表和视图,包含数据库、表、字段类型及访问权限等 |
performance_schema | 为MySQL服务器运行时状态提供了一个底层监控功能,主要用于收集数据库服务器性能参数 |
sys | 包含了一系列方便DBA和开发人员利用performance_schema性能数据库进行性能调优和诊断的视图 |
mysql:该mysql不是指mysql服务,而是指mysql的客户端工具
-e选项可以在Mysql客户端执行SQL语句,而不用连接到MySQL数据库再执行,对于一些批处理脚本,这种方式尤其方便
mysql -h192.168.2.128 -P3306 -p123456 数据库名 -e "select * from stu"
mysqladmin:mysqladmin 是一个执行管理操作的客户端程序。可以用它来检查服务器的配置和当前状态、创建并删除数据库等
mysqladmin --help mysqladmin -uroot -p123456 drop 'test01'; mysqladmin -uroot -p123456 version;
mysqlbinlog:由于服务器生成的二进制日志文件以二进制格式保存,所以如果想要检查这些文本的文本格式,就会使用到mysqlbinlog日志管理工具
mysqlshow:mysqlshow 客户端对象查找工具,用来很快地查找存在哪些数据库、数据库中的表、表中的列或者索引
mysqldump:mysqldump 客户端工具用来备份数据库或在不同数据库之间进行数据迁移。备份内容包含创建表,及插入表的SQL语句
mysqlimport/source:mysqlimport 是客户端数据导入工具,用来导入mysqldump 加 -T 参数后导出的文本文件
如果需要导入sql文件,可以使用mysql中的source 指令
source /root/xxx.sql