数据库之DDL表的操作
一、数据类型
1、面试题
char和varchar的区别
1相同之处:两者都是32位长度字符串类型
2不同之处:
char类型是固定长度,一次性提供32字符长度的存储空间,存不满,用空格补充;最多为255个字符。
varchar是可变长度,会计算判断字符串长度,按需分配存储空间,会另外占用一字节来记录字符长度,超过255,会用2字节记录长度,最多为65535个字符。
char和varchar如何选择?
(1) char类型,固定长度的字符串列,如手机号,身份证号,银行卡号,性别等
(2) varchar类型,不确定长度的字符串可以使用
2、enum枚举类型
enum(‘bj’,‘sh’,‘sz’,‘cq’)
索引分别为 0 1 2 3,数字类禁止使用enum
3、数字类型
1、tinyint
极小整数数据类型-128 - 127
2、int
手机号是无法存储到int的,一般使用char类型存储手机号
4、时间
1、timestamp
1970-01-01 至 2038-01-19
2、datetime
1000-01-01 至 9999-12-31
二、表属性
1、存储引擎:engine=InnoDB
2、字符集:charset=utf8mb4
utf8和utf8mb4的区别:
一个中文在utf8中占3个字节长度,在utf8mb4中占4个字节,但是utf8支持的字符不多,有可能出现乱码状态,最好使用utf8mb4。
3、排序规则(校对规则collation)
主要针对英文字符串大小写问题
三、列的属性和约束
主键:primary key(PK)
值必须唯一,不可重复,不可为空,数字列,整数列,无关列,自增的。是一种约束,也是一种索引类型,在一张表中只能有一个主键。
非空:not null
列的值不能为空,对于普通列来讲,尽量设置为not null
默认值:default
数字列默认值使用0,字符串类型设置为null
唯一: unique
比如手机号,身份证号不能重复
自增: auto_increment
针对数字列自增长,自动生成顺序值
无符号:unsigned
针对数字列,非负数就是无符号
注释:comment
描述
四、SQL语句应用
1、DDL(数据定义语言)
库操作
1、建库
mysql> create database free charset utf8mb4;
Query OK, 1 row affected (0.01 sec)
2、查询建库信息 (属于DQL)
mysql> show create database free;
+----------+------------------------------------------------------------------+
| Database | Create Database |
+----------+------------------------------------------------------------------+
| free | CREATE DATABASE `free` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ |
+----------+------------------------------------------------------------------+
3、改库
mysql> alter database liyu charset utf8mb4;
将库liyu的字符集由latin1变成utf8mb4
4、删库
mysql> drop database liyu;
Query OK, 0 rows affected (0.02 sec)
表操作
建表建库规范:
1、表名,库名必须是小写字母(因为windows中不区分大小写,一样的文件名两套大小写就无法区分)
2、不能以数字开头
3、不支持-,支持_
4、内部函数名不能使用
5、名字和业务功能有关
1、建表
create table liyu (
ID int not null primary key AUTO_INCREMENT comment '学号';
name varchar(255) not null comment '姓名';
age tinyint unsigned not null default 0 comment '年龄';
gender eunm('m','f','n') not null default 'n' comment '性别'
)charset=utf8mb4 engine=innodb;
2、改表
a.修改表结构(添加,删除列)
以上表中添加列(手机号15891007817)
alter table liyu add telnum char(11) not null unique comment '手机号';
在name后加上qq列
alter table liyu add qq varchar(255) not null unique comment 'qq号' after name;
在首列上添加sid
alter table liyu add sid varchar(255) nit null unique comment '学生号' first;
将上面添加的列删除
alter table liyu drop qq;
查看列信息
desc liyu;
mysql> desc student;
+--------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | tinyint(3) unsigned | NO | | 0 | |
| gender | enum('m','f','n') | NO | | n | |
+--------+---------------------+------+-----+---------+----------------+
show create table liyu; 查看建表语句
b.修改列的数据类型
将age的属性改为int
alter table liyu modify age int;
2、DCL(数据控制语言)
这里面最重要的就是grant授权和revoke取消授权
3、DML(数据操作语言)
1、insert
mysql> insert into student (name,age,gender) values ('liyu',23,'f');
mysql> select * from student;
+----+------+-----+--------+
| id | name | age | gender |
+----+------+-----+--------+
| 1 | liyu | 23 | f |
+----+------+-----+--------+
2、update(结合where)
mysql> select * from student;
+----+------+-----+--------+-------+
| id | name | age | gender | qq |
+----+------+-----+--------+-------+
| 1 | liyu | 23 | f | |
| 2 | free | 22 | m | 56787 |
+----+------+-----+--------+-------+
mysql> update student set qq='123456' where id=1;
mysql> select * from student;
+----+------+-----+--------+--------+
| id | name | age | gender | qq |
+----+------+-----+--------+--------+
| 1 | liyu | 23 | f | 123456 |
| 2 | free | 22 | m | 56787 |
+----+------+-----+--------+--------+
3、delete
逻辑删除,如果遇上大数据几千万行数据这样删除非常慢
mysql> select * from student;
+----+------+-----+--------+--------+
| id | name | age | gender | qq |
+----+------+-----+--------+--------+
| 1 | liyu | 23 | f | 123456 |
| 2 | free | 22 | m | 56787 |
+----+------+-----+--------+--------+
mysql> delete from student where id=2;
mysql> select * from student;
+----+------+-----+--------+--------+
| id | name | age | gender | qq |
+----+------+-----+--------+--------+
| 1 | liyu | 23 | f | 123456 |
+----+------+-----+--------+--------+
物理删除,truncate,DDL操作
mysql> truncate table student;
面试题:
delete和truncate的区别
1、delete逻辑逐行删除,不会降低自增长的起始值,效率很低,碎片较多,会影响到性能。
2、truncate物理删除,将表段中的区进行清空,不会产生碎片,性能较高。只能全表清空!!!要删几行还是得用delete。
伪删除:
使用update代替delete,进行伪删除
1、添加状态列state(1代表存在,0代表删除)
mysql> alter table student add state tinyint not null default 1;
mysql> select * from student;
+----+------+-----+--------+--------+-------+
| id | name | age | gender | qq | state |
+----+------+-----+--------+--------+-------+
| 1 | liyu | 23 | f | 123456 | 1 |
| 3 | free | 22 | m | 789 | 1 |
+----+------+-----+--------+--------+-------+
2、使用update模拟delete
mysql> update student set state=0 where id=3;
mysql> select * from student;
+----+------+-----+--------+--------+-------+
| id | name | age | gender | qq | state |
+----+------+-----+--------+--------+-------+
| 1 | liyu | 23 | f | 123456 | 1 |
| 3 | free | 22 | m | 789 | 0 |
+----+------+-----+--------+--------+-------+
3、业务语句修改,只查state为1的
mysql> select * from student where state=1;
+----+------+-----+--------+--------+-------+
| id | name | age | gender | qq | state |
+----+------+-----+--------+--------+-------+
| 1 | liyu | 23 | f | 123456 | 1 |
+----+------+-----+--------+--------+-------+
4、DQL(数据查询语言)
1、select
作用:获取MySQL中的数据行
a、单独使用select,select @@xxx,获取参数信息
mysql> select @@port;
+--------+
| @@port |
+--------+
| 3306 |
b、select 函数( )
ysql> select now(); 查询时间
+---------------------+
| now() |
+---------------------+
| 2021-05-24 17:22:32 |
+---------------------+
mysql> select database(); #查询在哪个库
+------------+
| database() |
+------------+
| free |
+------------+
c、SQL92标准的使用语法
select语法执行顺序(单表)
select开始 ------> from 子句 ------>where 子句------>group by 子句-------->select后执行条件-------->having 子句------->order by ------->limit
from
select * from 表名 #适合表数据行较少,生产中使用较少
select name,age from 表名
where
where配合等值查询(查询city表中城市为中国的)
select * from world.city where countrycode='CHN';
where配合不等值查询(查询世界上人口小于1000人的城市)
select * from world.city where population<1000;
where配合模糊查询(查询国家代号是c开头的城市)
select * from worl.city where countrycode like 'c%';
like语句在Mysql中,不要出现%在前面的情况,因为效率很低,不走索引
where配合逻辑连接符(and,or查询城市人口在1w到2w之间的)
select * from world.city where population>10000 and population<20000;(不包括1w和2w)
select * from world.city where population between 10000 and 20000;(包括1w和2w)
查询一下美国或中国的城市信息(union all)
select * from city where countrycode='CHN'
union (all)
select * from city where countrycode='USA'
union会去重,union all不会去重
group by
group by配合聚合函数应用
聚合函数:
avg(),sum(),count(),max(),min(),group_concat()
group_concat()是列转行的意思
统计每个国家的总人口数
select countrycode,sum(population) from city group by countrycode;
统计每个国家的城市个数
select countrycode,count(id)from city group by countrycode;
统计每个国家的省名字列表
select countrycode,group_concat(district) from city group by countrycode;
统计中国每个省的城市名列表
select district,group_concat(name) from city where countrycode='CHN' group by district;
统计中国每个省的总人口数
select district,sum(population) from city where countrycode='CHN' group by district;
having
having相当于where,不过只能用在group by 后面
统计中国每个省的总人口数大于1000w的省及总人口数
select district,sum(population) from world.city where countrycode='CHN' group by district having sum(population)>1000000 ;
having后的条件是不走索引的,可以进行一些优化手段处理
order by
统计中国每个省的人口,并将人口排序
select district,sum(population) from world.city where countrycode='CHN' group by district order by sum(population);
要反序排列就加上desc
limit
统计中国每个省的人口,并降序输出,显示前5名
select * from world.city where countrycode='CHN' order by population desc limit 5;
显示6-10行
limit 5,5; #跳过前5行,再显示5行
五、多表连接
四张表的结构如下:
1、内连接 A join B on A.x=B.y
查找a老师和他教的课程名
select teacher.tname,course.cname from teacher join course on teacher.tno = course.tno where teacher.tname='a';
2、统计一下每门课程的总成绩
select course.cnme,sum(sc.score) from course join sc on course.cno = sc.cno group by course.cno;
group by在sql_mode中受的影响,如果group by后面是主键就不会出现错误。
3、查询oldguo老师教的学生姓名列表
select teacher.tname,group_concat(student.sname)
from teacher
join course
on teacher.tno=course.tno
join sc
on course.cno=sc.cno
join student
on sc.sno=student.sno
where teacher.tname='oldguo';
4、查询所有老师教的学生姓名列表
select teacher.tname,group_concat(student.sname)
from teacher
join course
on teacher.tno=course.tno
join sc
on course.cno=sc.cno
join student
on sc.sno=student.sno
group by teacher.tno;
别名
表别名(as)
select te.tname,st.sname from teacher as te join student as st on .......
六、索引
1、索引的分类
1、索引作用
索引类似于书中的目录的作用,目的是为了优化查询
2、索引的种类(算法)
B树索引(重点B-tree,B+tree,B*tree)
Hash索引
R树
Full text
GIS
3、B+tree
B+tree比B-tree多了相邻叶子节点的双向指针,方便连续访问,范围查询,查看的范围是相邻的(比如>5)
4、B*tree
mysql用的最多的就是B*tree
相比于B+tree多了枝节点之间的双向指针。
2、索引的生成方式
1、在功能上的分类
a、辅助索引(S)怎么构建B树结构的?
1、辅助索引是基于表的列进行生成的
2、取出索引列的所有值(取出所有键值)
3、进行所有键值的排序
4、将所有的键值按顺序落到Btree索引的叶子节点上
5、进而生成枝节点和根节点
6、叶子节点除了存储键值之外,还存储了相邻叶子节点的指针,另外还会保存原表数据的指针(page)。
b、聚集索引( C)怎么构建B树结构的?
1、建表时有主键列(ID)
2、表中进行数据存储,会按照ID列的顺序,有序的存储一行一行的数据到数据页上(这个动作叫做聚集索引组织表)
3、表中的数据页被作为聚集索引的叶子节点,相当于把表整行的值放在了叶子节点
4、把叶子结点的主键值生成上层枝节点和根节点
辅助索引只是把单列的值拿出来做叶子节点,而聚集索引是把整行的值拿出来当做叶子节点。辅助索引是为了辅助聚集索引的。
2、辅助索引细分
a、单列的辅助索引
b、联合多列辅助索引(覆盖索引)
c、唯一索引
3、关于索引树的高度受什么影响?
1、数据行多,要分库分表
2、索引列的字符长度如果很长就会影响高度,前缀索引
3、char,varchar,char类型可能会影响高度,要合理设计表的数据类型
4、enum 优化索引高度,能用则用
3、索引的管理命令
我们可以先做一个压力测试,给数据库oldboy库创建一个表,表里写入100万行数据,再进行100个用户,20000次并发的测试
create table t100w (
id int,num int,
k1 char(2),
k2 char(4),
dt timestamp);
delimiter //
create procedure rand_data(in num int)
begin
declare str char(62) default 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
declare str2 char(2);
declare str4 char(4);
declare i int default 0;
while i<num do
set str2=concat(substring(str,1+floor(rand()*61),1),substring(str,1+floor(rand()*61),1));
set str4=concat(substring(str,1+floor(rand()*61),2),substring(str,1+floor(rand()*61),2));
set i=i+1;
insert into t100w values (i,floor(rand()*num),str2,str4,now());
end while;
end;
//
delimiter ;
插入100w条数据:
call rand_data(1000000);
退出数据库,在命令行输入100个用户,2000次并发
mysqlslap --defaults-file=/etc/my.cnf \
--concurrency=100 --iterations=1 --create-schema='oldboy' \
--query="select * from oldboy.t100w where k2=' XYVW '" engine=innodb \
--number-of-queries=2000 -uroot -p密码 -verbose
可以看到没有索引执行完特别慢,要花费700多秒
rk
Running for engine rbose
Average number of seconds to run all queries: 770.099 seconds
1、创建普通索引
mysql> alter table t100w add index idx_k2(k2);
给k2列创建索引
创建索引之后,我们再进行上述测试
Average number of seconds to run all queries: 0.281 seconds
只花费了0.28秒!这是什么概念,索引真牛!
我们查看一下创建的索引
mysql> desc t100w;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | YES | | NULL | |
| num | int(11) | YES | | NULL | |
| k1 | char(2) | YES | | NULL | |
| k2 | char(4) | YES | MUL | NULL | |
| dt | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
k2列的MUL就是辅助索引
mysql> show index from t100w\G
*************************** 1. row ***************************
Table: t100w
Non_unique: 1
Key_name: idx_k2
Seq_in_index: 1
Column_name: k2
Collation: A
Cardinality: 3611
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
2、创建唯一索引
mysql> alter table t100w add unique index idx_k1(k1);
ERROR 1062 (23000): Duplicate entry 'Od' for key 'idx_k1'
可以用上述命令试,如果建不成就说明有重复值
3、创建前缀索引(针对字符串)
mysql> alter table city add index idx_name(name(5));
4、创建联合索引
创建city表的population和countrycode
mysql> alter table city add index idx_co_po(countrycode,population);
5、删除索引
首先可以先查看一下索引
mysql> show index from t100w;
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t100w | 1 | idx_k2 | 1 | k2 | A | 3611 | NULL | NULL | YES | BTREE | | |
+-------+------------+----------+--------------+-------------+-
删除索引
mysql> alter table city drop index idx_k2
4、执行计划
1、作用
上线新的查询语句之前,进行提前预估语句的性能
在出现性能问题时,找到合理的解决思路
2、执行计划获取
mysql> desc select * from oldboy.t100w where k2='XYVW'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t100w
partitions: NULL
type: ref
possible_keys: idx_k2
key: idx_k2
key_len: 17
ref: const
rows: 292
filtered: 100.00
Extra: NULL
type:ref 索引的应用级别 *****
possible_keys: idx_k2 可能会使用到的索引
key: idx_k2 实际上使用的索引
key_len: 17 与联合索引有关,联合索引覆盖长度
rows: 292 查询的行数(越少越好)
Extra: NULL *****
3、执行计划的分析
type:ref 索引的应用级别
从上到下,性能依次变好
ALL 全表扫描,不走索引,有没有索引都不走
1、没建立索引,所以不走
2、建立索引,但是不走的(不以索引列为查找条件;用like,前后加%,如果要加,只给最后面加%;!=)
Index 全索引扫描
mysql> mysql> desc select k2 from t100w;
+----+-------------+-------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | t100w | NULL | index | NULL | idx_k2 | 17 | NULL | 997344 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+
range 索引范围扫描(辅助索引:>,<,<=,>=,or,like,in,!=在主键列上,这些type都是range)
ref 辅助索引等值查询
eq_ref 在多表连接查询时,on的条件列是唯一索引或主键
const/system 主键或唯一键等值查询
NULL 查不到数据的时候就显示NULL
Extra: NULL
using filesort出现这个就是索引设计的不合理,就要进行order by,group by 与where的联合索引
where A group by B order by C
索引:idx_A_B_C(A,B,C)
面试题:
有一条select语句平常查询时很快,突然有一天很慢,会是什么原因?
1、索引失效,统计数据不真实,索引有自我维护的能力,对于表内容变化比较频繁的情况下,有可能会出现索引失效,一般删除或者重建
2、锁冲突,由于锁的问题把所有的资源全都耗尽了,啥操作都做不了
七、存储引擎
1、InnoDB引擎介绍及引擎分类
1、介绍
类似于linux系统中的文件系统,存储引擎是作用在表上的,也就意味着,不同的表可以有不同的存储引擎类型
2、功能
数据读写
数据安全和一致性
提高性能
热备份
自动故障恢复
高可用方面支持
3、oracle的mysql种类
show engines;就可以查看
掌握InnoDB和MyISAM的区别
+--------------------+
| Engine |
| CSV |
| MyISAM |
| MEMORY |
| ARCHIVE |
| InnoDB |
+--------------------+
其他mysql的引擎
PerconaDB :默认是XtraDB
MariaDB:默认是InnoDB
其他的存储引擎支持
TokuDB
RocksDB
MyRocks
这三种存储引擎的共同点:压缩比较高,数据插入性能极高
面试题:
如何查看整个数据库下所有InnoDB的表和MyISAM的表
mysql> select table_schema,table_name,engine from information_schema.tabre engine = "InnoDB";
4、存储引擎操作类命令
使用select确认会话存储引擎
mysql> select @@default_storage_engine;
+--------------------------+
| @@default_storage_engine |
+--------------------------+
| InnoDB |
+--------------------------+
默认存储引擎设置
vim /etc/my.cnf
[mysqld]
default_storage_engine=InnoDB
扩展:
在线修改mysql参数
会话级别:set default_stroage_engine=myisam,只影响到当前会话
全局级别:set gloabl default_stroage_engine=myisam,不影响当前会话,只影响到新开的会话。
以上两种方法,在重启之后会失效,除非参数添加至/etc/my.cnf文件里。
2、InnoDB物理存储结构
ll /data/mysql/data
ib_buffer_pool 缓存池
ibdata1:系统数据字典信息(统计信息什么表,表是什么状态),undo(回滚)表空间等数据
ib_logfile0:redo(重做)日志文件,事务日志文件
ib_logfile1:redo日志文件,事务日志文件
ibtmp1:临时表空间磁盘位置,存储临时表
frm :存储表的列信息,列名,列数据类型
ibd:表的数据行和索引 -又叫做表空间
表=ibd+frm+ibdata1
mysql的存储引擎日志:
redo log:ib_logfile0,ib_logfile1 重做日志
undo log:ibdata1,ibdata2(存储在共享表空间中),回滚日志
临时表:ibtmp1,在做join union操作产生临时数据,用完就自动删除
表由ibd+frm+ibdata1组成,下列命令可以删除表空间:ibd
alter table t1 discard tablespace;
将t1表的ibd拷贝为ibd.bak,执行上述命令后ibd文件就不在了,此时如果再把ibd.bak拷贝为ibd是没有用的,因为数据库内部已经把索引等数据删除掉了,要想恢复就得用到下列命令导进来,注意要修改ibd的权限为mysql
alter table t1 import tablespace;
3、事务的特性
作用是什么?
事务为了保证DML语句作为一个单元进行ACID的特性,影响了DML语句(insert,update,delete,一部分select),影响了以下特性
原子性:所有语句作为一个单元全部执行成功或全部取消,不能出现中间状态(发红包,两条-和+语句要同时执行)
一致性:如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致性(a账户100块,b账户0元,a给b发50,最后两者和还是100)
隔离性:事务之间不相互影响
持久性:事务成功完成后,所做的所有更改都会准确的记录在数据库中,所有的更改不会丢失
4、事务的生命周期
1、从begin开始,到commit结束
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu;
+-----+----------+------+------+
| sno | sname | sage | ssex |
+-----+----------+------+------+
| 1 | zs | 16 | f |
| 2 | liyu | 23 | m |
| 3 | xixi | 12 | f |
| 4 | qianqian | 22 | f |
+-----+----------+------+------+
4 rows in set (0.00 sec)
mysql> delete from stu where sno>3;
Query OK, 1 row affected (0.00 sec)
mysql> delete from stu where sno=1;
Query OK, 1 row affected (0.01 sec)
mysql> select * from stu;
+-----+-------+------+------+
| sno | sname | sage | ssex |
+-----+-------+------+------+
| 2 | liyu | 23 | m |
| 3 | xixi | 12 | f |
+-----+-------+------+------+
2 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
如果没有按下commit,那么另外开一个窗口还可以看到4条语句;
在另外个窗口进行begin,delete操作时做不了,必须得等另外一个窗口完事才能做,这就是事务的隔离性。
2、事务的回滚,rollback
mysql> delete from stu where sno=2;
Query OK, 1 row affected (18.43 sec)
mysql> select * from stu;
+-----+-------+------+------+
| sno | sname | sage | ssex |
+-----+-------+------+------+
| 3 | xixi | 12 | f |
+-----+-------+------+------+
1 row in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu;
+-----+-------+------+------+
| sno | sname | sage | ssex |
+-----+-------+------+------+
| 2 | liyu | 23 | m |
| 3 | xixi | 12 | f |
+-----+-------+------+------+
2 rows in set (0.00 sec)
3、自动提交
如果你输入了begin,但是一直不commit也不rollback,一直占用着资源,由于事务的隔离性,别人也做不了操作,所以mysql想出了下面的办法
不写begin,直接写DML语句,系统直接就给你commit了
5、锁介绍
锁定的意思,提供的是隔离的功能,需要配合undo+隔离级别一起来实现
InnoDB的锁级别:行级锁,改某一行,就会锁定某一行,别人不能同时修改这行数据。涉及普通的所等待和死锁。
6、InnoDB核心参数
1、双一标准之一:innodb_flush_log_at_trx_commit=1
作用:控制了redo buffer刷写策略,是一个安全参数,5.6版本的默认参数
mysql> select @@innodb_flush_log_at_trx_commit;
+----------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------+
| 1 |
+----------------------------------+
1:每次事务提交,都会立即刷下redo到磁盘(redo buffer----->每事务----->os buffer----->磁盘)
0:当事务提交时,不立即做日志写入操作,而是每秒钟将log buffer中的数据写入文件系统缓存并且秒fsync磁盘一次
2:每次事务提交引起写入文件系统缓存