数据库知识要点,面试向

数据知识要点

数据库原理、sql语句、mysql数据库、数据库优化、redis

数据库原理

知识点:事务、范式、多粒度和意向锁、XS锁、封锁协议、两段锁协议、死锁、隔离级别

事务ACID

事务就是指数据库的要做的一件事情,可以是一条sql语句,可以是一系列操作。把这些操作总体当作一个要么完成要么不完成的事情来看,完成就是commit,不完成就是rollback

事务的四个特性:

A 原子性 要么完成,要么rollback

C 一致性 事物之行前后保持一致性

I 隔离性 事务之间不影响也不可见

D 持久性 修改是永久的,即使系统奔溃,也不可以出问题

### 并发一致性问题

脏数据、不可重复读、修改丢失、幻影读

脏数据:就是读出来的数据,由于被别人修改了,但是丢改又取消了,其实没有修改,但是读出来的数据是修改的,所以是脏数据

不可重复读:读了两次数据,但是读的时候,别的事务修改了数据的值,导致读的不对

修改丢失:多个事务同时读取数据,然后修改,但是先写入的被后修改的覆盖了

幻影读:范围读取的时候,由于别的事务的修改,导致两次读取结果不一样

写锁X:加了之后,只有我可以读改数据,其他程序不可以读写

读锁S:加了之后,只有我和其他加了读锁读事务可以读,不可以写也不可以加X锁,只可以加S锁

封锁协议

一级、二级、三级封锁协议

一级封锁协议:写入之前加X锁,直到事务结束,释放X。防止丢失修改,同时只有一个事务可以修改数据

二级封锁协议:一的基础上,在读取之前加S,读完释放S。防止读取脏数据,因为A修改x的值的时候,没办法第二次读取,如果回滚了,读取到的数据是脏数据。

三级封锁协议:一的基础上,读之前加S,事务结束释放S。防止不可重复读。

多粒度锁和意向锁

锁的粒度可以是表级也可以是行级别,mysql中myisam就是表,innoDB就是行级别

意向锁:为了更好的支持多粒度锁

IX锁:获取某个行的X锁之前,需要获得表的IX锁

IS锁:获取某个行的S锁之前,需要获得表的IS锁及更强锁

表的IX锁和X锁不兼容,就是说加了IX,不可以加表的X,只能加行的X

原理:

没有意向锁的话,如果想获取一个表的X锁,就需要对表的X锁和每一行的X锁进行检测,非常消耗资源。

但是有了意向锁就不一样了,如果有一个事务获得了行的X锁,那它一定获得了表的IX锁,其他事务如果想来获取这个表的锁,就不可以,只能获得行的X锁

两段锁协议

就是说加锁和解锁分为两段来执行,可以对不同事务中的所有加锁解锁操作串行,判断是否可以冲突可串行化调度

冲突可串行化调度,就是说按照一个串行顺序调度,不会出现死锁

死锁

预防:一次封锁法:一次获得所有资源,顺序封锁法:按照一个合理的顺序封锁

诊断和解除:超时法,等待图法(检测回路),从一个最小事务,释放它的所有资源

隔离级别

未提交读:修改未提交就可以读,不能防任何

已提交读:只能读取已经提交的结果,可以防止脏数据

可重复读:事务多次读取结果一样,防止不可重复读,不防幻影

可串行化 :事务串行执行,不会互相干扰,不会出现一致性问题,需要加锁实现

多版本并发控制MVCC

InnoDB实现提交读和可重复读的一种实现。可串行无法实现。

基本实现:

数据有版本快照,只可以读取已经提交的快照,从而防止脏数据和不重复读,脏数据和不重复读是由于读取了为提交的修改导致的。

多版本指的是多个版本的快照,储存在Undo日志中。

每一个事务会有一个版本号。日志就记录了操作这些数据的版本号等信息。

ReadView结构,里保存了未提交的事务列表的版本号,通过比较快找的版本号和列表的版本号,如果快照小,则修改为提交,可以使用,如果快照大,则不能使用,如果在列表中间,则需要判断在列表中就表示没提交,提交读不可,不在就可以提交读。可重复读不可以。

 

MVCC不可以解决幻影读,所以使用nextkeylocks解决幻影读

recordlocks和gaplocks结合,锁定索引的一个区间

 

范式

第一、第二、第三范式

第一范式:属性不可分

第二范式:非主属性只依赖键码

第三范式:不存在非主属性的函数依赖传递

BCNF:每个决定因素都包含码(我的理解是都在码内)

第四范式:没有非平凡的非函数依赖的多值依赖

多值依赖:就是说ABC三属性,AC虽然决定B,但是B中很多组值(B1B2、B3B4B5)只取决于A。

比如课程、老师、书本,不同老师用不同的书,一门课好几个老师,课程可以决定一坨老师和书,

所以老师和书都是对课程多值依赖的。

非平凡就是C不为空,例子里就是有课本。

mysql数据库

对比

之前是myisam,现在是InnoDB

InnoDB:支持事务,支持行级锁、支持外键、聚簇索引、多版本控制、commit和rollback、热备份

myisam:不支持事务,表级锁、不支持外键、非聚簇索引

索引实现

B+Tree索引或者哈希索引

哈希索引:O1复杂度,查询速度快,只支持单个条目查询

B+tree索引:支持范围查找

全文索引:倒排索引实现,记录关键字到文档的映射。用于全文查找关键字

空间数据索引:myisam支持,用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。

BTree比红黑好:1因为出度大,所以查找快。2磁盘预读,索引和文件放在一起

索引种类

单列索引、多列索引、前缀索引、覆盖索引

覆盖索引:索引包含需要查询的字段的值

索引使用

优点:加快查询速度,随机IO变顺序IO,避免排序和分组创立临时表

使用:中大型表,特大表代价太大,小表直接扫描

索引总结

https://github.com/Snailclimb/JavaGuide/blob/master/docs/database/%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B4%A2%E5%BC%95.md

https://github.com/Snailclimb/JavaGuide/blob/master/docs/database/MySQL%20Index.md

InnoDB

  • Record lock:单个行记录上的锁

  • Gap lock:间隙锁,锁定一个范围,不包括记录本身

  • Next-key lock:record+gap 锁定一个范围,包含记录本身

 

数据库优化

大表优化

限定数据的取值范围

读写分离,主库写,从库读

垂直分区:按照相关性和列拆分乘多个表,优点:减少读取数据量,缺:增加了冗余和连接

水平分区:水平拆分可以支持海量的数据

分区要谨慎使用,不然跨区会有很大代价

索引优化

限制索引数量

最左侧原则

频繁查询和使用的列索引

频繁更新的列不要索引

避免冗余的索引

 

 

其他优化和规范

https://github.com/Snailclimb/JavaGuide/blob/master/docs/database/MySQL%E9%AB%98%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E8%A7%84%E8%8C%83%E5%BB%BA%E8%AE%AE.md

 

 

 

redis数据库

redis是一个内存中的Nosql数据库,广泛用于缓存方向。也经常用来做分布式锁。此外还支持事务,支持LUA脚本,支持持久化和集群方案。高性能,高并发。

线程模型

单线程,单线程其实是指他的文件事务分派器是单线程的。

redis是由于:

多个socket

IO多路复用程序

文件事务分派器

时间处理器

组成。

流程:多个socket并发产生多个操作,然后IO多路复用程序从socket中监听,将socket中时间放在一个队列中,文件事务分派器按照事务将事件一个一个派发给事件处理器。

redis和memcached区别

类型:redis是数据库,而memcached是缓存系统

数据类型:redis五种,string、set、map、list、Zset

集群:redis原生支持,memcached不支持,需要程序支持

线程:redis是单线程的非阻塞IO复用,memcached是多线程的多路IO复用

持久化:redis支持持久化,memcached只是一个缓存系统

操作:redis:批量操作、假事务、不同类型不同curd,memcached支持curd和其他少量操作

内存淘汰

可以设置过期时间。

定期删除:定期扫描一定数量的设置了过期时间的key,过期则删除。不全部扫描,因为开销太大。

惰性删除:定期删除肯定长时间会存在很多没有被删掉的过期变量,需要惰性删除,就是说检查一下这个key,然后删除。

因为删除还会导致大量过期的变量,所以引入淘汰机制

6种

设置了过期中最近最少使用

设置了过期中最快过期

设置了过期中随机

所有中最近最少使用

所有中随机

不删除

4.0后加了两种:

设置了过期中最少使用

全部中最少使用

持久化

快照持久化:定期产生快照,然后对快照进行备份

AOF持久化(只追加文件持久化):每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。每秒同步一次,最多损失一秒的数据。实时性很好,是目前对主流方案。

4.0后支持混合持久化

事务

事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。redis支持事务的方式就是一起做,顺序执行。

缓存穿透和缓存雪崩

缓存穿透:大量的请求不在缓存中,需要请求数据库

解决方法:处理无效key过期、布隆过滤器(类似于白名单,判断key是否合法)

缓存雪崩;短时间缓存大量失效,导致请求直接交给数据库

解决方法:事前:保证redia集群的高可用性,选择合适的淘汰机制,事中:ehcache缓存 + hystrix限流&降级,避免MySQL崩掉,事后:持久化机制快速回复。

 

 

sql语句

 略

猜你喜欢

转载自www.cnblogs.com/CooperXia-847550730/p/12820497.html
今日推荐