剑指Java面试-Offer直通车 关系型数据库 笔记2

 3-1 数据库架构

考察了我们对数据库的认识 模块化的思想

   

存储模块 将数据存入磁盘中

但是光有存储是不行的 还需要组织 并且以后还会用到这些数据 因此还需要用到程序实例 利用逻辑结构 映射到我们的物理结构

并且提供 管理数据的方式 这就是程序实例

   

存储管理:将数据的格式和文件的分割进行统一的管理

缓存机制:为了更快 将取出来的数据快存放在缓存里面

扫描二维码关注公众号,回复: 9337628 查看本文章

sql解析 :为了外界指令能够操作我们的数据库

日志管理:sql操作需要记录下来 方便我们查找错误 灾难恢复

权限划分:每一个人都有自己的权限划分 dba做的事情

容灾机制:还需要考虑到异常机制 当数据库挂掉了该如何恢复

索引管理: 提供sql查询的速度

锁管理: 并发

   

   

面试的重点模块:

索引模块和锁模块

   

索引的灵感来自与字典 快速的查找到我们需要的数据

问题1

   

问题2

索引最后好建立在一定范围内的数据

   

问题3

下面几节课都是利用这几个结构 来建立索引 并找出最好的结构

   

   

   

3-2 优化你的索引-运用二叉查找树

2019年8月25日

16:01

   

   

二叉查找树

对于树中的每一个节点x 左边小于父亲 右边大于父亲

例如查找6 会先经过5 找到7 再找到6

时间复杂度 O(logn)

   

缺点 数据库会经过删除和插入等操作

   

因为每次都会io 从文件系统里面读取数据 每一层都会这样

但是由于二叉树只有两个节点 但是数据库里面块有很多 导致了二叉树的层次非常高 因此效率大大降低

就会想到Btree了

   

   

3-3 优化你的索引-运用B树

2019年8月25日

16:07

   

如果每一个节点最多有m个孩子 那么这样的树就是m阶b树

下面就是3阶B树

每一个存储块(树节点)尽可能存储多的信息 降低io次数

   

   

   

   

   

3-4 优化你的索引-运用B+树

2019年8月25日

17:39

   

   

B+是B树的变体

   

叶子节点才存放值 这里的Q就是具体的数据 非叶子直接只存放索引 因此非叶子节点能够存储更多的关键字了 树更矮了

叶子节点都是按照大小顺序来做排列的 链接起来的作用是方便我们直接在叶子节点里面做统计 因为我们知道下一个叶子节点的指针 而不是回到根部再去检索了

   

   

   

   

3-5 优化你的索引-运用Hash以及BitMap

2019年8月25日

18:03

   

   

   

   

数据的值 如果是固定的话 可以考虑BitMap 目前Oracle中有该索引

通常使用的索引结构 就是B+树

   

   

   

   

3-6 密集索引和稀疏索引的区别

2019年8月25日

18:20

   

   

密集索引的概念是 叶子节点保存的不仅仅是键值 还保存了位于同一行记录里的 其它列的信息

一个表里面只能创建一个密集索引

   

稀疏索引:叶子节点只保存了键位信息和该行的地址

   

总的来说 密集索引的叶子节点里面有键值,有数据 而稀疏索引里面只有指向数据的地址

在mysql中 主流的引擎myisam 和 innodb

   

左边是innodb 右边是myisam

   

实战演示

第一张表

第二张表

.frm是 表的结构文件

.ibd 是innodb的 就是person的数据和索引 这里person表中有很多数据 shop表中没有数据

.MYI 是myisam的 代表索引

.MYD 是数据 这里为0 因为没有数据

   

   

   

3-7 索引额外的问题之如何调优Sql

2019年8月25日

18:37

   

   

   

索引能够避免全表扫描去查找数据 提高搜索效率

由索引衍生出来的问题

第一个问题 优化sql

1.使用慢日志定位sql

下面使用一个例子来展示这个思路

慢日志就是用来记录执行比较慢的sql 分析他的原因

第一个是 10s 代表如果超过了10s就会被记录到慢日志里面 一般设置为1s钟就认为慢了

除了上面的变量 我们还需要了解系统的状态

这个就是慢查询的数量 注意这个是本次会话 慢查询的条数 一旦重启客户端 就会清空

   

先打开慢查询 还有设置慢查询时间

   

我们还可以直接修改my.ini 修改配置

重启数据库

   

制造慢查询 先插入数据 这里老师插入了两百万条数据

   

打开日志 大概花费了 6s才查询出来

   

第二步:

利用explain 去分析这条sql语句

   

最优到最差

这里的type=all 代表本次查询走的是全表扫描

   

extra

   

第三步

修改sql 尽量让sql走索引

   

因为account是唯一索引 我们可以将name替换成account

   

第二条语句虽然还是慢查询 但是速度比之前的快了很多

   

但是有时候 就是需要利用name来进行排序 这时我们就可以给name添加索引了

这一次更快了

   

这个会走account的索引 而不是id shop是myisam引擎

因为我们的查询优化器来做决定的 mysql的查询优化器的目标是尽可能的走索引 而且是最严格的索引来消除尽可能的数据行.

这里因为密集索引的叶子节点 把其它数据也存放到了叶子节点当中 因此效率要不稀疏索引要低

   

   

3-8 索引额外问题之最左匹配原则的成因

2019年8月25日

21:28

   

   

联合索引就是多个列组成的索引

   

这个就是联合索引

当我们where 两个条件的时候 走的就是这个联合索引 注意这两个条件就是索引字段

   

如果我们把title给去掉 依然走的是联合索引

   

当我们只保留title就会发现不会走索引了 走了全表扫描 这个是最差的性能

   

   

产生的原因

mysql创建复合索引的规则 是首先会对复合索引最左边的 索引字段进行排序 在第一个排序字段的基础上 再对第二个索引字段进行排序 类似order by

所以第一个字段是绝对有序的 第二个字段是无序的了 因此使用第二个字段使用条件判断是用不到索引的 这个就是联合索引最左匹配原则

   

   

   

   

3-9 索引额外问题之索引是建立越多越好吗

2019年8月25日

22:07

   

   

答案肯定不是

   

   

   

   

3-10 锁模块之MyISAM与InooDB关于锁方面的区别

2019年8月25日

22:09

   

   

   

问题一:

利用实际的例子 进行讲解

打开多个会话 模拟并发

两张表 引擎不同

   

   

先讲 myisam引擎

一边查询1-2000000

当一边正在查询大量数据 另一边进行更新时 会发现表级锁 因为我们更新的是2000001 所以是表级锁

这样可以显示的加上读锁

直到我们自己释放读锁

   

读锁又叫做 共享锁 当两边都是读操作的时候 即使加了锁 也不影响

上面都是先上读锁 再上写锁的情况 下面是先上写锁

   

会等待前面的update语句执行完成 再执行select

   

两个写锁 写锁又叫做排他锁 需要先把之前的执行了 才执行后面的

   

添加for update 就可以给select上排他锁了

   

   

innodb

innodb支持事务

我们需要先关闭 自动提交 注意这个只是在当前session里面有效

因为mysql底层对select做了优化 这样才能加共享锁 lock in share mode

先执行上面的 再执行下面的 就会发现锁住了

当commit之后 update语句才能够成功

当我们不走索引的时候innodb还是会用到表级锁 走索引的时候是利用行级锁

   

X是排他

   

   

select count的时候

myisam提供了一个变量保存表的行数 但是innodb每次都是重新扫一道表的

   

   

   

实际操作乐观锁

这个是程序1

先不执行 这时程序二 进行操作

程序二先执行了

回到程序1 就会发现未更新 这时用户程序按照自己的业务逻辑去做处理

   

   

   

   

   

   

   

   

   

   

3-12 锁模块之数据库事务的四大特性

2019年8月25日

22:30

   

   

   

持久性代表一个事务一旦提交 他对数据库的修改是持久的 当系统或者介质出现故障的时候 确保已提交事务的更新不能丢失 持久性主要在于dbms的恢复性能

innodb来讲 就会将所有的操作 写入一个专门的文件 并在数据库启动的时候从此文件进行恢复操作 这个文件就是redo log文件 保证了innodb的持久性

   

   

3-13 锁模块之事务并发访问产生的问题以及事务隔离机制

2019年8月25日

23:33

   

   

假设有两个事务 取款和存款

   

   

mysql tx的默认隔离级别 可重复读

设置隔离级别 为读未提交

创建一张表

   

脏读 一个事务读到另一个事务未提交的数据

   

一个session进行减少 但是未提交

另一个事务 读到了 未提交的数据

   

第二个隔离级别 读已提交 不允许事务读到其它事务未提交的数据

   

一个事务前后两次读取的数据不一致 重复读

不可重复读 使用可重复读事务隔离级别以上 来避免

   

   

   

幻读

   

当一个事务对数据库进行操作 发现只有3条记录 这个事务只想对这3条记录进行update 但是另一个事务又插入了一条数据

当第一个事务 更新之后就会发现多更新了一条 就好像出现幻觉一样

   

   

   

   

   

   

   

3-15 锁模块之当前读和快照读1

2019年8月27日

14:41

   

   

但是我们实际操作中 发现了mysql的innodb 的可重复读的事务隔离级别下就可以避免幻读

当前读就是加了锁的增删改查语句 当前读:就是读取了当前最新版本 并且读取之后还需要保证其它并发事务不能修改当前事务

   

快照读 就是不加锁 但是 不是在序列化的情况下 因为序列化会将所有语句加锁

快照读是为了提高并发性能的考虑 快照读有可能读的不是最新版本的数据

   

   

update允许实例

   

   

   

   

   

   

3-17 锁模块小结

2019年8月27日

15:20

   

   

   

   

3-18 关键语法讲解

2019年8月27日

15:21

   

   

   

创建表

   

   

   

注意这里只是一张表 所以select的列 里面只能有聚集函数和分组列

多表查询的话 就可以不止有

   

   

having

   

   

   

   

   

   

   

3-20 彩蛋之面试的三层架构

2019年8月27日

15:34

   

   

   

   

   

   

猜你喜欢

转载自www.cnblogs.com/alalajijun/p/12347256.html