zoukankan      html  css  js  c++  java
  • 数据库知识要点,面试向

    数据知识要点

    数据库原理、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结合,锁定索引的一个区间

     MCVV详解参考:https://www.codercto.com/a/88775.html

    范式

    第一、第二、第三范式

    第一范式:属性不可分

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

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

    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语句

     略

  • 相关阅读:
    python面试题
    面试总结
    552 Student Attendance Record II 学生出勤记录 II
    551 Student Attendance Record I 学生出勤纪录 I
    547 Friend Circles 朋友圈
    546 Remove Boxes 移除盒子
    543 Diameter of Binary Tree 二叉树的直径
    542 01 Matrix 01 矩阵
    3.1 特性
    2.6 datetime 模块
  • 原文地址:https://www.cnblogs.com/CooperXia-847550730/p/12820497.html
Copyright © 2011-2022 走看看