MySQl看这一篇就够了

MySQL分享

1、数据库结构

语句

DDL(Data Definition Languages):数据定义语句,经常使用的语句关键字主要包括 create、drop、alter等操做表结构html

DML(Data Manipulation Language):数据操做语句,经常使用的语句关键字主要包括 insert、delete、udpate 和select 等操做数据mysql

DCL(Data Control Language):数据控制语句,用户的访问权限和安全级别。主要的语句关键字包括 grant、revoke 等算法

结构

链接者:不一样语言的代码程序和mysql的交互(SQL交互)sql

链接池:管理、缓冲用户的链接,线程处理等须要缓存的需求数据库

管理服务和工具组件:系统管理和控制工具,例如备份恢复、Mysql复制、集群等缓存

SQL接口:接受用户的SQL命令,而且返回用户须要查询的结果安全

解析器:对SQL进行解析,判断语法是否正确session

查询优化器:SQL语句在查询以前会使用查询优化器对查询进行优化数据结构

举个例子并发

-- 下面的SQL company 和 name 都有索引,索引类型也相同,字段类型也相同
-- 索引字段能匹配的数据越少,优先使用该索引字段
select * from dept_table where company = '集团' and name = '财务部';

缓存:若是查询缓存有命中的查询结果,查询语句就能够直接去查询缓存中取数据

存储引擎:INSERT DELETE UPDATE SELECT 数据的一种方式

存储引擎名称 特色 应用场景
InnoDB 支持事务、行锁、支持MVCC多版本并发控制,并发性高 应用OLTP业务系统
MyISAM 不支持事务,MySQL8以后被废弃了,并发很低,资源利用率也很低 应用OLAP业务系统,建议生产环境尽可能少少使用 MyISAM 存储引擎
MariaDB columnstore 列式存储引擎,高压缩功能 数据仓库,OLAP业务系统
数据库的引擎级别?
  • [ ] A. 软件级别(即安装MySQL时就已经指定引擎类型)
  • [ ] B. 数据库级别
  • [ ] C. 表级别

OLTP(On-Line Transaction Processing):联机事务处理,好比增删改查,完成一笔交易处理

OLAP(On-Line Analytical Processing):联机分析处理,支持复杂的分析操做,侧重决策支持,作数据分析,决策,好比 ElasticSearch

SQL执行过程

2、事务

事务特性(ACID)

原子性(A):要么全完成,要么全不完成

一致性(C):在事务开始以前和事务结束之后,数据库的完整性约束没有被破坏(好比A给B转帐100元,A减小100,B增长100)

隔离性(I):事务之间互不干扰

持久性(D):事务提交后保存起来了

隔离级别(对执行事务起做用)

读未提交(read uncommitted):A事务变动后没提交,B能看到

读已提交(read committed):A事务变动后提交,B才能看到

可重复读(repeatable read):一个事务执行过程当中看到的数据,老是跟这个事务在启动时看到的数据是一致的

串行化(serializable):同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行

并发问题

脏读:读未提交的隔离级别下,A事务读到B更新却没commit的数据

不可重复读:侧重修改,A事务两次读取同一数据两次不一致

幻读:侧重数据增减,A事务两次读取数据不一样

事务隔离级别与并发问题

事务隔离级别 脏读 不可重复读 幻读
读未提交(read uncommitted)
读已提交(read committed)
可重复读(repeatable read)
串行化(serializable)

验证事务的隔离级别

事务A 事务B
begin; begin;
select * from dept_table; --V1
select * from dept_table; --V2
update dept_table set name = '研发部' where id = 1;
select * from dept_table; --V3
commit;
select * from dept_table; --V4
commit;
select * from dept_table; --V5

事务相关SQL

# 设置事务隔离级别
set session transaction isolation level read uncommitted;

set session transaction isolation level read committed;

set session transaction isolation level repeatable read;


# 查询当前事务隔离级别
select @@tx_isolation;

# 查询全局事务隔离级别
select @@global.tx_isolation;

# 开启事务
begin;
start transaction;

# 提交事务
commit;

# 回滚事务
rollback;

隔离级别的实现

多版本并发控制 MVCC(Multi-Version Concurrency Control): MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,在每行数据都增长两个隐藏字段,一个记录建立的版本号,一个记录删除的版本号,用于实现提交读和可重复读这两种隔离级别。而未提交读隔离级别老是读取最新的数据行,无需使用 MVCC。可串行化隔离级别须要对全部读取的行都加锁,单纯使用 MVCC 没法实现

版本号
  1. 系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增

  2. 事务版本号:事务开始时的系统版本号

可重复读的操做
  1. SELECT:读取建立版本 <= 当前事务版本号,而且删除版本为空或大于当前事务版本号的记录。这样能够保证在读取以前记录是存在的
  2. INSERT:将当前事务的版本号保存至行的建立版本号
  3. UPDATE:新插入一行,并以当前事务的版本号做为新行的建立版本号,同时将原记录行的删除版本号设置为当前事务版本号
  4. DELETE:将当前事务的版本号保存至行的删除版本号

插入一条新数据(事务版本号 = 1)

id name create_version delete_version
1 Tom 1

执行更新操做(事务版本号 = 2)

update table set name= 'Tom2' where id = 1;
id name create_version delete_version
1 Tom 1 2
1 Tom2 2

删除操做(事务版本号 = 3)

delete from table where id = 1;
id name create version delete version
1 Tom2 2 3

查询操做要知足两个条件才能查询出来

  1. 删除版本号 大于 当前事务版本号或为空,就是说删除操做是在当前事务启动以后作的
  2. 建立版本号 小于或者等于 当前事务版本号 ,就是说记录建立是在事务中(等于的状况)或者事务启动以前
可重复读状况下的演示
-- 1. T事务(假设:当前事务版本号 = 1)插入一条数据
-- create_version = 1 delete_version = null
insert into `up`.`dept_table`(`id`, `company`, `name`) values (5, '总部', '综合创新部');

-- 1. A事务(假设:当前事务版本号 = 2) 查询数据 4条结果
select * from dept_table; 

-- 2. B事务(假设:当前事务版本号 = 3) 更新ID = 1 的数据
update dept_table set name = '金融服务部' where id = 5;

-- 3. A事务继续查询
select * from dept_table;
快照读

当执行select操做时 InnoDB默认会执行快照读,会记录下此次select后的结果,以后select 的时候就会返回此次快照的数据,即便其余事务提交了不会影响当前select的数据,这就实现了可重复读了。快照的生成当在第一次执行select的时候,也就是说假设当A开启了事务,而后没有执行任何操做,这时候B insert了一条数据而后commit,这时候A执行 select,那么返回的数据中就会有B添加的那条数据。以后不管再有其余事务commit都没有关系,由于快照已经生成了,后面的select都是根据快照来的

示例1 B事务的查询结果是否有A新增的数据?

A事务 B事务
start transaction; start transaction;
insert into up.dept_table(id, company, name) values (6, '总部', '综合创新部');
select * from dept_table;
commit;
select * from dept_table;
commit

示例2 B事务的两次查询结果是否相同?第二次查询是否有A新增的数据?

A事务 B事务
start transaction; start transaction;
select * from dept_table;
insert into up.dept_table(id, company, name) values (6, '总部', '综合创新部');
select * from dept_table;
commit;
select * from dept_table;
commit;
当前读

对数据修改的操做(update、insert、delete、select …... lock in share mode、select …... for update)都是采用当前读的模式。在执行这几个操做时会读取最新的记录,即便是别的事务提交的数据也能够查询到。假设要update一条记录,可是在另外一个事务中已经delete掉这条数据而且commit了,若是update就会产生冲突,因此在update的时候须要知道最新的数据。也正是由于这样因此才致使上面咱们测试的那种状况

示例

A事务 B事务
start transaction; start transaction;
select * from dept_table; -- V1
insert into up.dept_table(id, company, name) values (6, '总部', '综合创新部');
commit;
select * from dept_table; -- V2
update dept_table set name = '新部门' where id = 6;
select * from dept_table; -- V3
commit;
快照读 当前读
select * from table select * from table for update
select * from table lock in share mode
insert、delete、insert

3、InnoDB的锁

锁概念

锁做用

数据库锁机制简单来讲,就是数据库为了保证数据的一致性,使各类共享资源在被并发访问时变得有序而设计的一种规则

锁机制

MySQL的锁机制比较简单,最显著的特色时不一样的存储引擎支持不一样的锁机制,咱们锁知道的,InnoDB支持行锁,有时也会升级为表锁,MyISAM只支持表锁

行锁和表锁的特色
表锁 行锁
开销小 开销大
加锁快 加锁慢
不会出现死锁 会出现死锁
锁粒度大 锁粒度小
发生锁冲突的几率高 发生锁冲突的几率低
并发度相对低 并发度相对高

InnoDB的锁类型

读锁(共享锁)

简称S锁,若事务T对数据对象加上读锁,则事务T能够读但不能修改,其余事务只能再对该数据加读锁不能加写锁,直到T释放该数据的读锁。即一个事务在读取一个数据行时,其余事务也能够读,但不能对该数据进行增删改的操做

读锁的实现方式

  1. 自动提交模式下的select查询语句,不须要加任何锁,直接返回查询结果,这是一致性非锁定读
  2. 经过 select ...... lock in share mode 在被读取的行记录或行记录的范围上加一个锁,让其余事务能够读,可是想要申请写锁,就要被阻塞
-- 查询是否自动提交模式
show variables like '%auto%';
写锁(排它锁)

简称X锁,若事务T对数据对象加上写锁,事务T能够读也能够修改,其余事务不能再对该数据加任何锁,不能读也不能写,直到T释放该数据上的锁。即一个事务获取了一个数据行的写锁,其余事务就不能再获取该行的其余锁,写锁优先级最高

写锁的实现方式

  1. INSERT、DELETE、UPDATE语句的操做都会对行记录加写锁
  2. 经过 select ...... for update 对读取的记录行上加写锁,其余任何事务就不能对锁定的行上加任何锁了,不然会被阻塞
MDL锁(meta data lock)

在事务A中开启查询,会自动得到一个MDL锁,事务B就不能够执行任何DDL语句的操做

事务A 事务B
begin; begin;
select * from score_table;
alter table score_table add num tinyint(1) not null default 0; -- 阻塞
commit;
commit;
-- 查询进程列表
show full processlist;
意向锁

在MySQL存储引擎InnoDB中,意向锁是表级锁。并且有两种意向锁类型,分别为意向共享锁和意向排他锁

  1. 意向共享锁(IS):是指在给一个数据行加共享锁前必须先取得该表的IS锁
  2. 意向排他锁(IX):是指在给一个数据行加排他锁前必须先取得该表的IX锁

其实意向锁的做用跟MDL锁相似,都是防止在事务进行过程当中,执行DDL语句的操做而致使数据不一致

InnoDB行锁种类

在默认的事务隔离级别为RR,而且参数 innodb_locks_unsafe_for_binlog = 0 的模式下,行锁的种类有三种

  1. 单个行记录锁(record lock):锁定一个行记录

注:主键和惟一索引都是行记录的锁模式。在RC隔离级别下,只有 record lock 记录锁模式

  1. 间隙锁(gap lock):锁定一个区间
  2. 记录锁和间隙锁的组合叫作 next-key lock:锁定行记录 + 区间

注:普通索引默认的就是 next-key lock模式

单个行记录的锁
-- 查看索引
show index from dept_table;

company 字段有索引

事务A 事务B
begin; begin;
update score_table set name = 'a' where score= 60;
update score_table set name = 'aaa' where score= 60; -- 出现锁等待
update score_table set name = 'bbb' where score= 70; -- 正常更新
commit;
commit;

company 字段无索引

事务A 事务B
begin; begin;
update score_table set name = 'a' where score= 60;
update score_table set name = 'bbb' where score= 70; -- 出现锁等待
commit;
commit;

InnoDB的锁是加在索引上的

间隙锁

在RR事务隔离级别,为了不幻读现象,引入了 gap lock,但它只锁定记录的范围,不包含记录自己,即不容许在次范围内插入任何数据

事务隔离级别RR

事务A 事务B
begin; begin;
select * from score_table where score < 80 lock in share mode;
insert into score_table(name, score) values ('dd', 75); -- 等待
commit;
commit;

事务隔离级别RC

-- 查看事务隔离级别
show variables like '%tx_isolation%';
事务A 事务B
begin; begin;
set session transaction isolation level read committed; set session transaction isolation level read committed;
select * from score_table where score < 80 lock in share mode;
insert into score_table(name, score) values ('dd', 75); -- 可提交
commit;
commit;

证实间隙锁只是针对RR隔离级别才管用,从锁的角度避免了幻读发生

next-key locks

记录锁与间隙锁的组合,当InnoDB扫描表记录时,会先对选中的索引加上记录锁,再对索引记录两边的间隙加上间隙锁

事务A 事务B
begin; begin;
select * from score_table where score < 85 for update;
insert into score_table(name, score) values ('dd', 85); -- 等待
commit;
commit;

证实不光锁定 score < 85 这个区间的数据,还包含 85 这个值的自己

锁等待和死锁

锁等待是指一个事务过程当中产生的锁,其余事务须要等待上一个事务释放它的锁,才能占用该资源。若是该事务一直不释放,就须要持续等待下去,直到超过锁等待时间,会报一个等待超时的错误

-- 查询锁等待时间
show variables like '%innodb_lock_wait%';

-- 修改全局变量方式
set global innodb_lock_wait_timeout = 2;

set @@global.innodb_lock_wait_timeout = 5;

-- 修改当前事务变量方式
set innodb_lock_wait_timeout = 2;

死锁是指两个或两个以上的进程在执行过程当中,因争夺资源而形成的一种互相等待的现象,即事务1锁住数据D1,正请求对D2加锁,而事务2锁住了D2,正请求加锁D1,这样就会致使死锁

事务A 事务B
begin; begin;
update score_table set name = 'a' where score= 60;
update score_table set name = 'bbb' where score= 70;
update score_table set name = 'b' where score= 70;
update score_table set name = 'aaa' where score= 60;
commit;
commit;
-- 查看死锁展现信息
show engine innodb status;
解决死锁
  1. 若是不一样程序并发存取多个表,或者涉及多行记录时,尽可能约定以相同的顺序访问表,能够大大下降死锁的机会
  2. 业务中尽可能采用小事务,避免使用大事务,要及时提交或者回滚事务,可减小死锁产生几率
  3. 在同一个事务中,尽量作到一次锁定所须要的全部资源,减小死锁产生几率
  4. 对于很是容易产生死锁的业务部分,能够尝试使用升级锁粒度,经过表锁定来减小死锁产生几率

4、索引

理解索引

在工做中,开发人员在开发初期因为多种缘由设计表的过程当中,没有给后面可能会常常访问的字段增长索引这个概念,因为后期的业务调整需求变动且数据也在不断增加,会根据某些已存在的字段做为条件查询。后面再增长索引会很麻烦,须要考虑现有系统的可用性,还须要考虑到当前增长索引列的内容。因此建立索引须要结合现有业务还要预知后期可能存在的业务变动,使设计的数据表伸缩性更强,在设计初期把数据表设计完善也可以让后面的开发事半功倍。

索引利用好了就是一辆”法拉利“,利用很差就成了”三轮车“了。

索引是什么?为何要使用索引?

帮助MySQL作高效查询的一种数据结构,比如是一本书的目录,经过目录能快速找到要查看的内容

提升查询效率

索引分类

从存储结构划分:BTree索引(B-Tree或B+Tree索引),Hash索引

从应用层划分:主键索引,惟一索引,普通索引,复合索引,全文索引,SPATIAL

根据键值的逻辑顺序和表数据行的物理存储顺序:汇集索引,非汇集索引

汇集索引:叶子节点存放表中全部行数据记录的信息

非汇集索引:不是汇集索引就是非汇集索引

索引什么时候无效?

索引通常在 where,order by,group by,表链接的条件列起做用

索引无效:

-- 1. 查询条件的值是null
explain select * from dept_table where name = null;

-- 2. NOT条件 好比:<>、in、not in、exists、not exists
explain select * from dept_table where name <> '新部门';

explain select * from dept_table where name in ('财务部2'); -- 可使用索引

explain select * from dept_table where name in ('财务部2', '新部门'); -- 不使用索引

explain select * from dept_table where name not in ('新部门'); -- 一个和多个都不使用索引

explain select * from dept_table where exists (select * from dept_table where name = '新部门');

explain select * from dept_table where not exists (select * from dept_table where name = '新部门');

-- 3. LIKE通配符在前面
explain select * from dept_table where name like '%部门';

explain select * from dept_table where name like '部门%'; -- 可使用索引

explain select * from dept_table where name like '新%门%'; -- 可使用索引

-- 4. 条件列上包括函数
explain select * from dept_table where upper(name) = 'NEW';

explain select * from dept_table where name = upper('new'); -- 可使用索引
索引存到哪里了?用什么方式存储?

索引是存储到磁盘上的文件

MyISAM引擎和InnoDB引擎共有文件

.frm文件:在MYSQL中创建任何一张数据表,在其数据目录对应的数据库目录下都有对应表的.frm文件,.frm文件是用来保存每一个数据表的元数据(meta)信息,包括表结构的定义等,.frm文件跟数据库存储引擎无关,也就是任何存储引擎的数据表都必须有.frm文件,命名方式为数据表名.frm,如user.frm. .frm文件能够用来在数据库崩溃时恢复表结构

InnoDB引擎文件

.ibd文件:单表表空间文件,每一个表使用一个表空间文件(file per table),存放用户数据库表数据和索引

MyISAM引擎

.MYD:即 my data,表数据文件

.MYI:即 my index,索引文件

索引原理

MySQL为何没有使用二叉树或红黑树?

推荐一个数据结构网站:www.cs.usfca.edu/~galles/visualization/Algorithms.html

若有 三、一、二、十、九、0、四、6这8个数据

哈希结构

  • 直接查询:如今要从8个数中查找6这条记录,只须要计算6的哈希值,即可快速定位记录,时间复杂度为O(1)
  • 范围查询:若是要进行范围查询(大于4的数据),那这个索引就彻底没用了

二叉树结构(右子树大于左子树)

  • 直接查询:如今要从8个数中查找10这条记录,先查找3,6>3,查找10,查找两次就能够了
  • 范围查询:若是要进行范围查询(大于3的数据),直接查询大于3的右子树就好了

不使用二叉树缘由:若是索引列查入的数据是单边增加的,会致使查询时依旧变慢,最差状况时间复杂度会变成O(N)

红黑树结构(是一种平衡的二叉查找树)

特色:

  1. 根节点是黑色
  2. 节点是红色或者黑色
  3. 每一个叶子节点都是黑色的空节点(null)
  4. 每一个红色节点的两个子节点都是黑色的
  5. 从任意节点到其每一个叶子的全部路径都包含相同数量的黑色节点
  • 直接查询:如今要从10个数中查找10这条记录,先查找4,10>4,查找6,10>6,查找到8,10>8,查找到9,10>9,查找到10
  • 范围查询:若是要进行范围查询(大于6的数据),直接查询大于6的右子树就好了
  • 问题:当数据量变大后,树的高度依然是很大,读取I/O磁盘次数仍是不少

为何想要减小磁盘I/O次数?

MySQL的数据实际是存储在文件中,而磁盘IO的查找速度是要远小于内存速度的,因此减小磁盘IO的次数能很大程度的提升MySQL性能

磁盘I/O为何慢?

磁盘IO时间 = 寻道 + 磁盘旋转 + 数据传输时间

从磁盘读取数据时,系统会将逻辑地址发给磁盘,磁盘将逻辑地址转换为物理地址(哪一个磁道,哪一个扇区)。 磁头进行机械运动,先找到相应磁道,再找该磁道的对应扇区,扇区是磁盘的最小存储单元

性能对比

机械硬盘的连续读写性能很好,但随机读写性能不好。

  • 顺序访问:内存访问速度是硬盘访问速度的6~7倍
  • 随机访问:内存访问速度就要比硬盘访问速度快上10万倍以上

随机读写时,磁头须要不停的移动,时间都浪费在了磁头寻址上。 而在实际的磁盘存储里,是不多顺序存储的,由于这样的维护成本会很高

局部性原理与磁盘预读

因为存储介质的特性,磁盘自己存取就比主存慢不少,再加上机械运动耗费,磁盘的存取速度每每是主存的几百分分之一,所以为了提升效率,要尽可能减小磁盘I/O。为了达到这个目的,磁盘每每不是严格按需读取,而是每次都会预读,即便只须要一个字节,磁盘也会从这个位置开始,顺序向后读取必定长度的数据放入内存。这样作的理论依据是计算机科学中著名的局部性原理:

当一个数据被用到时,其附近的数据也一般会立刻被使用。

程序运行期间所须要的数据一般比较集中。

因为磁盘顺序读取的效率很高(不须要寻道时间,只需不多的旋转时间),所以对于具备局部性的程序来讲,预读能够提升I/O效率。

预读的长度通常为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操做系统每每将主存和磁盘存储区分割为连续的大小相等的块,每一个存储块称为一页(在许多操做系统中,页得大小一般为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,而后异常返回,程序继续运行。

BTree(B-Tree)和B+Tree闪亮登场

度(m):节点数据存储个数

深度关系(h):h=log(m+1)N

B+Tree相对于BTree区别:

  1. 非叶子节点只存储索引键,从而下降B+树的高度,进而减小IO次数
  2. 叶子节点存储整张表的全部行数
MyISAM索引实现

MyISAM引擎使用B+Tree做为索引结构,叶节点的data域存放的是数据记录的地址

这里设表一共有三列,假设咱们以Col1为主键,上图是一个MyISAM表的主索引(Primary key)示意。能够看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是惟一的,而辅助索引的key能够重复。若是咱们在Col2上创建一个辅助索引,则此索引的结构以下图所示

一样也是一颗B+Tree,data域保存数据记录的地址。所以,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,若是指定的Key存在,则取出其data域的值,而后以data域的值为地址,读取相应数据记录

因此MyISAM是非“汇集索引”,从索引文件和数据文件分别存储就能够看出。也与下面介绍的InnoDB的“汇集索引”作区分

InnoDB索引实现

虽然InnoDB也使用B+Tree做为索引结构,但具体实现方式却与MyISAM大相径庭

第一个不一样:MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。InnoDB的数据文件自己就是索引文件,从文件存储上就能够知道,表数据文件自己就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,所以InnoDB表数据文件自己就是主索引


​ InnoDB主索引(同时也是数据文件)的示意图

能够看到叶节点包含了完整的数据记录。这种索引叫作汇集索引。由于InnoDB的数据文件自己要按主键汇集,因此InnoDB要求表必须有主键(MyISAM能够没有),若是没有显式指定,则MySQL系统会自动选择一个能够惟一标识数据记录的列做为主键,若是不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段做为主键,这个字段长度为6个字节,类型为长整形。

第二个不一样:与MyISAM索引的不一样是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的全部辅助索引都引用主键做为data域


​ InnoDB辅助索引(辅助索引得到主键索引)的示意图

这里以英文字符的ASCII码做为比较准则。汇集索引这种实现方式使得按主键的搜索十分高效,可是辅助索引搜索须要检索两遍索引:首先检索辅助索引得到主键,而后用主键到主索引中检索得到记录。

问题
  1. InnoDB引擎为何必须有主键且建议使用整型自增主键?

空间方面:uuid存储空间更大

比较关系:索引之间有比较关系,整型的比较会更快

结构方面(最重要一点):使用自增主键保证插入数据都是向叶子节点后面顺序插入,若是使用uuid比较,生成的uuid不必定顺序插入,致使插入到节点的中间位置,若是该节点已经满了,会致使节点进行分裂变成新的结构

  1. 为何InnoDB引擎的非主键索引数据存储的是主键值?

一致性和节省存储空间

  1. 节点的度设置为多少合适?

B-Tree节点的度设置等于一个页,每次新建节点直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,就实现了一个节点的载入只须要载入一次I/O

  1. 联合索引的底层存储结构是长什么样?

4、总结

  1. 数据库结构、一条SQL执行过程
  2. 事务隔离级别、并发问题、可重复读的实现过程
  3. 锁的使用、锁等待、死锁
  4. 索引分类、索引如何存储、索引什么时候无效、MySQL为何使用B+Tree做为索引结构、MyISAM索引实现、InnoDB索引实现
  5. 磁盘读写过程
  6. MySQL主从复制过程

5、主从复制

事务相关的重要日志

redolog:数据日志

undolog:ibdata1

binlog:逻辑日志

相关文章
相关标签/搜索