数据库基本原理
-
函数依赖、范式:注意先搞懂码、候选码、主属性、非主属性的相关概念。
第一范式:属性不可分,列不可拆分
第二范式:在第一范式基础上,所有非主属性完全依赖于候选码
第三范式:在第二范式基础上,消除传递依赖
BC范式:在第三范式基础上,不存在主属性对于码的部分函数依赖与传递函数依赖。BC范式性质: (1)所有非主属性对每一个码都是完全函数依赖; (2)所有的主属性对于每一个不包含它的码,也是完全函数依赖; (3)没有任何属性完全函数依赖于非码的任意一个组合。
多值依赖:设R(U)是属性集U上的一个关系模式。X,Y,Z是U的子集,并且Z=U-X-Y。关系模式R(U)中多值依赖X→→Y成立,当且仅当对R(U)的任一关系r,给定的一对(x,z)值,有一组Y的值,这组值仅仅决定于x值而与z值无关。
例 Teaching(C, T, B) 对于C的每一个值,T有一组值与之对应,而不论B取何值。因此T多值依赖于C,即C→→T。
平凡多值依赖和非平凡的多值依赖
若X→→Y,而Z=Ф,即Z为空,则称X→→Y为平凡的多值依赖。 否则称X→→Y为非平凡的多值依赖。
第四范式:关系模式R<U,F>∈1NF,如果对于R的每个非平凡多值依赖X→→Y(Y ⊈ X),X都含有码,则R<U,F>∈4NF
4NF就是限制关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖
SQL
MySQL
-
一级封锁协议解决丢失修改问题 二级封锁协议解决读脏数据问题 三级封锁协议解决未提交读问题 四种隔离级别使用一级封锁协议后都没有丢失修改问题。 提交读解决读脏数据问题 可重复读解决不可重复读问题 可串行化解决幻读问题‘ 索引的优点: 1、加快查询速度,大大减少需要扫描的行数 2、避免进行排序和分组
-
MySQL的InnoDB存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,并且所有的锁都是在事务提交后同一时刻被释放,这被称为隐式锁定。
-
MySQL默认端口号:3306
-
普通的select不上任何锁,因为是快照读
-
for update:详解mysql的for update
-
在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据; 在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据; 在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;
-
数据库系统将B树、B+树的一个节点的大小设置为页的大小(16k),使得一次 I/O 就能完全载入一个节点。 B+树的节点中只保存用来索引的关键字,不保存数据,因此每个节点能容纳更多元素,产生更多分支,更“矮胖”,IO次数少。
-
以下内容重要!
在 MySQL 中 InnoDB 存储引擎的最小存储单元是页, 页的大小默认是 16k,页就等价于B+树的一个结点!
-
每张表只能拥有一个聚簇索引
-
数据库的那些乱七八糟烦人的锁(数据库锁机制有这一篇就够了) (这篇文章基于oracle,有些地方和Mysql不一样)
-
乐观锁悲观锁:博客1 (这篇的乐观锁例子很好) 、博客2(这篇过程很清晰) 、博客3 、博客4
写入频繁使用悲观锁,读取频繁使用乐观锁 乐观锁: (1)开启事务 (2)读取版本号V1 (3)更新数据x和版本号version:update table set x=x+1, version=version+1 where id=xxx and version=V1; (4)在业务逻辑代码中判断(3)执行后更新的记录条数是否为0,若为0说明版本号已经变了,回滚事务并重试;否则提交事务。
-
为什么MyISAM会比Innodb的查询速度快? 博客
-
mysql存储引擎InnoDB、MyISAM、MEMORY总结
MEMORY是MySQL中一类特殊的存储引擎。它使用存储在内存中的内容来创建表,而且数据全部放在内存中 MEMORY存储引擎的表实际对应一个磁盘文件。该文件的文件名与表名相同,类型为frm类型只存储表的结构。而其数据文件,都是存储在内存中。有利于数据的快速处理,提高整个表的效率。但内存出现异常,重启或者关机会影响数据 MEMORY默认使用哈希索引。速度比使用B型树索引快。如果你想用B型树索引,可以在创建索引时指定。
-
联合索引、最左前缀原则:
多个单列索引和联合索引的区别详解(重要!!!)
多个单列索引在多条件查询时优化器会选择最优索引策略,可能只用一个索引,也可能将多个索引全用上! 但多个单列索引底层会建立多个B+索引树,比较占用空间,也会影响更新数据的效率,故如果只有多条件联合查询时最好建联合索引! 联合索引比对每个列分别建索引更有优势,因为索引建立得越多就越占磁盘空间,在更新数据的时候速度会更慢(比如说插入或者删掉一条数据,就要每颗b+树都做出相应改动)。 另外建立多列索引时,顺序也是需要注意的,应该将严格的索引放在前面,这样筛选的力度会更大,效率更高。 联合索引的最左前缀原则: 顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上 联合索引优化:在联合索引中将选择性最高的列放在索引最前面。 例如:在一个公司里以age 和gender为索引,显然age要放在前面,因为性别就两种选择男或女,选择性不如age。
-
覆盖索引就是只需要在一棵索引树上就能获取SQL语句所需的所有列数据,不必通过二级索引查到主键之后再去查询数据,也无需回表查询。 常见的方法是:将SQL要查询的字段,建立到联合索引里去。
-
B+树查询的时间复杂度是多少?
(m/2)*log(m)n 有n个节点,m路b+树,树高约为log(m)n层,每层线性搜索平均时间约为m/2; 如果每层采用二分搜索就是log(2)m*log(m)n
-
MVCC多版本并发管理(重要)
系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。 事务版本号:事务开始时的系统版本号。 MVCC多版本并发控制一般的实现方法是存储快照来实现的。 InnoDB实现方式是在每行记录后添加两个隐藏列(表项),分别是创建版本号(创建时的系统版本号)、过期版本号(更新或删除时的系统版本号)。 INSERT 时更新创建版本号,UPDATE/DELETE时更新过期版本号,这样一来在SELETE时,就只访问创建版本号小于当前事务版本号、过期版本号要么未定义要么在当前事务版本号之后的记录, 这样就可以保证:访问的记录是在本事务开始前就存在而且在本事务期间没有过期(被删除或被修改过的)。
-
binlog、redo log、undo log: 博客1、博客2
bin log在事务提交才将SQL语句写入日志、redo log在事务开始之后就逐步写入日志
Redis
-
redis默认端口号:6379
-
redis数据结构: Redis常用数据类型介绍、使用场景及其操作命令、 深入了解 Redis 底层数据结构
-
Redis缓存:
Redis中缓存预热,缓存雪崩,缓存击穿,缓存穿透的简单解释及解决方案。
阿里面试Redis最常问的三个问题:缓存雪崩、击穿、穿透(带答案)
缓存雪崩的解决方案: 1、在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值 缓存穿透的解决方案: 1、在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等 2、布隆过滤器:快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return 缓存击穿的解决方案: 1、设置热点数据永远不过期 2、使用互斥锁,这种解决方案思路比较简单,就是只让一个线程构建缓存,其他线程等待构建缓存的线程执行完,重新从缓存获取数据就可以了
-
Redis集群: