数据库三范式:
理解: 第一 数据库表中的每一列 不可再分 (原子性) 例如:城市划分为 省、市、区、xx街道、xx小区 细分到不可再分
第二 数据库中的每条记录都是唯一的(唯一性) 保证 数据完整不被混乱定义 ------例如同名同姓的人。身份证体现唯一性
第三 一个数据库表中,不能包含,已经在其他表的包含的非主键信息 ----例如学生表 有学生编号,老师表中有老师编号,学生表中就不能出现老师编号这种冗余的信息(所谓冗余,视情况业务需要而定)
建立三范式 : 优点 -- 可以减少繁冗的字段, 表的更新操作更快 空间存储占用较低
缺点 --在查询过程当中,通常都是多表查询, 难以进行索引优化(连表查询条件不用索引,可能会导致索引失效)
索引:
分为: 聚集索引 非聚集索引
---- 聚簇索引: 指主键索引, 键值的逻辑顺序按照物理顺序排列一致(唯一索引 ,每个表只能有一个主键索引)
---- 非聚簇索引:也就是指的主键索引外的索引,即键值的逻辑顺序不一致
也可说索引分为
主键索引 : 一张表中唯一的索引,只能有一个,不能有空值,其值为数据表自动创建
唯一索引: 一张表中唯一的索引,只能有一个。可以为空
普通索引: 提高查询效率
全文索引: 仅在MyISAM引擎下使用,只能支持Varchar char TEXT字段类型下支持查询
联合索引:组合表中多个字段创建的索引(遵循最左前缀匹配)
----最左匹配原则 在创建联合索引 匹配规则是从左开始匹配的 查询数据的时候,从左开始匹配
----索引的底层是一颗B+树构成,联合索引底层即为B+树构成,其是存在B+树的键值,由于B+树值只能根据一个值来确定索引关系,所以数据库依赖联合索引只能最左边字段开始构建
索引的优点 : 加快查询速度
缺点: 占用物理空间
维护时间长(创建索引的时候,根据数据的增加,维护索引的耗费的时间越长)
数据库索引失效的原因分为:
第一:模糊匹配 like
第二: 条件查询 or
第三: 函数计算 sum cout svg 等
第四: 范围查询 > 或者<
第五: 查询字段与表定义的字段类型不一 表中 age 类型是int 但是查询的时候用的是 where age=""
第六:连表查询条件不使用索引
第七:分组或者去重 group by 或者 Distinct
小表(这里指数据量小)不推荐创建索引(百万级别数据考虑)
因为数据少的情况下,增加索引 ---出现的现象,增加前查询可能比增加后查询速度快 起不到优化效果 反而会浪费空间和时间
B+树与 B树的区别
B树: 其叶子节点和非叶子节点,都存储了键值,查询时 ---时间复杂度好的情况下是 O(0) 不好就会出现 O(n log)
B+树:其叶子节点存数据,非叶子节点存关键字 稳定O (n)
B+树 叶子节点用链表连接,查询时 只需要扫描链表下的叶子节点 一次遍历就行, B树就需要循环遍历查询
B+树 优点
---减少IO次数
---查询效率稳定
---适合范围查询
覆盖索引: B+树在叶子节点存储了键值,有可能存当前键值以及正常数据,所有分为聚簇索引和非聚簇索引,在Innodb中,聚簇索引为主键,当表中没有主键索引时,数据库会主动选举唯一索引来代替主键索引,如果没有唯一索引,也会创建一个隐藏主键索引
索引下推: 5.6版本的查询优化技术
在索引下推的情况下 满足条件的数据,mysql服务器将满足条件的数据推送给存储引擎,让存储引擎通过索引判断推送的数据是否满足Mysql服务器的查询条件,只有将满足条件的数据返回给Mysql服务器
------优点 减少存储引擎查询的速度和Mysql服务器在存储引擎接收的次数
存储引擎
分为innodb 和myIsam
Innodb引擎支持事务
mylsam不支持事务
在他俩都支持B+树的数据结构的索引时,Innodb就是聚簇索引 mylsam就是非聚簇索引
Innodb有表、行(默认)锁,MylSAM支持表级锁
Innodb 必须有主键索引,没有的情况下,会主动寻找或者隐藏创建一个索引为主键索引
Innodb四大特性
插入缓冲
二次写
自适应哈希索引
预读
数据库事务:
ACID
原子性: 事务的最小单位,不能再分,要么全部成功,要么全部失败
一致性: 事务发生前后,数据保持一致
隔离性: 并发事务发生,A事务的发生,不会被其他事务所干扰
持久性: 事务一旦发生,将是永久性的变化
并发事务带来的问题:
脏读、幻读、不可重复读
脏读 ---事务A读取读取事务B更新的数据后,B事务回滚 即读未提交
不可重复读 ----事务两次读取到了不同的数据 B事务在A事务多次读取的过程中,B提交对数据经行了提交,导致读取的数据不一致
幻读 ---事务中两次读取的量不一样 当A事务对 abcd经行提交的时候,B事务,插入了一条数据具体的数据,导致A事务提交后发现 有一条数据没有修改,就好像发生了幻读一样
事务的隔离级别:
--- 读已提交 只允许读取已经提交的数据(避免脏读,存在不可重复度和幻读)
--- 读未提交 读取未提交的数据 (导致脏读、幻读、不可重复读)
--- 可重复读 避免脏读,不可重复读,但是不免不了幻读
--- 可串行化 避免以上问题, ----影响性能
数据库锁
当事务发生的时候,可能会导致读取到的数据不一致, 这个时候锁就出现了
从锁的粒度上分
--- 行级锁 粒度最小,减少数据库操作的冲突(加锁开销大) 加锁慢,可能会造成死锁
--- 表级锁 粒度最大的一种锁,对整张表经行加锁,实现简单,资源消耗少
--- 页级锁 趋于表级锁和行级锁中间的一种锁
从使用性质上分
--- 共享锁 S锁,又称读锁,仅针对与只读的操作
S锁允许多个事务经行加锁,但是允许加X锁,不能对数据经行修改,S锁当事务读取结束时,会迅速放开,不需要等到事务结束后
--- 排它锁 X锁,又称写锁,仅针对写的操作
X锁只允许一个事务对统一资源进行加锁,等事务处理结束后,才能经行访问
--- 更新锁 U锁,预定X锁,可以进行其他事务读,但是不能再经行U锁或者X锁
当读取的页数,要更新时,升级为X锁,U锁一直到事务结束才会放开,使用U锁 避免造成死锁
从主管上分
---乐观锁
---悲关锁
隔离级别与锁的关系
--- 读未提交, 读取数据不需要加共享锁
--- 读已提交 读取数据需要加共享锁,整个语句执行完成后,释放
--- 可重复读 读取数据需要加共享锁,但是再事务之前不会释放锁,必须等待事务执行完毕后,释放锁
--- 可串行化 该级别锁定整个范围的值,一直锁,直到事务结束
视图
---视图的存储过程 一个预编译的SQl语句,一次创建,多次使用
----存储过程和函数 函数有一个返回值,存储过程是通过函数反回的 ,可以有多个或者没有
函数在调用语句中可以直接调用,但是存储过程必须单独调用
数据库日志
常见日志
-----物理日志 又称重写日志(redo log)用来恢复未写入数据文件的已提交数事务数据 作用是确保事务的持久性
-----回滚日志 又称逻辑日志(undo log) 保证事务发生之前的数据是一个版本,用于回滚,同事可以提供多个版本并发控制下的读(MVCC), 保证事务的原子性
-----二进制日志 又称逻辑日志 (binlog) 用于主从同步或者数据同步中,,也可以用于数据库基于时间点的还原
-----错误日志(errorlog) 默认情况下,系统记录错误日志的功能是关闭的
-----普通日志 默认也是关闭的
MVCC 版本控制器,
---不可重复读 +幻读 采用 乐观锁+MVCC机制处理