数据库总结

Mysql基础

什么是事务?
Transaction

​ 事务是数据库并发控制的基本单位
​ 事务可以看作是一系列SQL语句的集合
​ 事务必须要么全部执行成功,要么全部执行失败(回滚)

事务的ACID特性
ACID是事务的四个基本特性

​ 原子性(Atomicity): 事务中所有操作全部完成或失败
​ —致性(Consistency): 事务开始和结束之后数据完整性没有被破坏
​ 隔离性(Isolation): 允许多个事务同时对数据库修改和读写
​ 持久性(Durability): 事务结束之后,修改是永久的不会丢失

事务的并发控制可能产生哪些问题
如果不对事务进行并发控制,可能会产生四种异常情况

​ 幻读(phantom read): —个事务第二次查出现第一次没有的结果
​ 非重复读(nonrepeatable read): 一个事务重复读两次得到不同结果
​ 脏读(dirty read): —个事务读取到另一个事务没有提交的修改
​ 丢失修改(lost update): 并发写入造成其中一些修改丢失

四种事务隔离级别
为了解决并发控制异常,定义了4种事务隔离级别

​ 读未提交(read uncommitted): 别的事务可以读取到未提交改变
​ 读已提交(read committed): 只能读取已经提交的数据
​ 可重复读(repeatable read): 同一个事务先后查询结果一样(mysql 默认)
​ 串行化(Serializable): 事务完全串行化的执行,隔离级别最高,执行效率最低

如何解决高并发场景下的插入重复
高并发场景下,写入数据库会有数据重复问题

​ 使用数据库的唯一索引
​ 使用队列异步写入
​ 使用redis等实现分布式锁

乐观锁和悲观锁
什么是乐观锁,什么是悲观锁

​ 悲观锁是先获取锁再进行操作。一锁二查三更新select for update
​ 乐观锁先修改,更新的时候发现数据已经变了就回滚(check and set)
​ 乐观锁一般通过版本号或者时间戳实现
​ 使需要根据响应速度、冲突频率、重试代价来判断使用哪一种

Mysql常用数据类型
字符串(文本)

​ CHAR、VARCHAR、TINYTEXT、TEXT

数值

​ TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT、FLOAT、DOUBULE

日期和时间

​ DATE、DATETIME、TIMESTAMP

InnoDB、MyISAM的区别

​ MyISAM不支持事务,InnoDB支持事务
​ MyISAM不支持外键,InnoDB支持外键
​ MyISAM只支持表锁,InnoDB支持行锁和表锁
​ MyISAM支持全文索引,InnoDB不支持全文索引

什么是索引?
为什么需要索引?

​ 索引是数据表中一个或者多个列进行排序的数据结构
​ 索引能够大幅提升检索速度(回顾下你所知道的查找结构)
​ 创建、更新索引本身也会耗费空间和时间

查找结构进化史

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html数据结构可视化工具

​ 线性查找: 一个个找;实现简单;太慢
​ 二分查找︰ 有序;简单;要求是有序的,插入特别慢
​ HASH: 查询快;占用空间;不太适合存储大规模数据
​ 二叉查找树︰插入和查询很快(log(n));无法存大规模数据,复杂度退化
​ 平衡树∶ 解决bst退化的问题,树是平衡的;节点非常多的时候,依然树高很高
​ 多路查找树: 一个父亲多个孩子节点(度);节点过多树高不会特别深
​ 多路平衡查找树: B-Tree

什么是B-Tree?

​ 多路平衡查找树(每个节点最多m(m>=2)个孩子,称为m阶或者度)
​ 叶节点具有相同的深度
​ 节点中的数据key 从左到右是递增的

B+Tree
B+Tree是B-Tree的变形

​ Mysql实际使用的B+Tree作为索引的数据结构
​ 只在叶子节点带有指向记录的指针(为什么?可以增加树的度)
​ 叶子结点通过指针相连。为什么?实现范围查询

Mysql索引的类型

​ 普通索引(CREATE INDEX)
​ 唯一索引,索引列的值必须唯一(CREATE UNIQUE INDEX)
​ 多列索引
​ 主键索引(PRIMARY KEY),一个表只能有一个
​ 全文索引(FULLTEXT INDEX) ,InnoDB不支持

什么时候创建索引?
建表的时候需要根据查询需求来创建索引

​ 经常用作查询条件的字段(WHERE条件)
​ 经常用作表连接的字段
​ 经常出现在order by, group by 之后的字段

创建索引有哪些需要注意的?

​ 非空字段NOT NULL ,Mysql很难对空值作查询优化
​ 区分度高,离散度大,作为索引的字段值尽量不要有大量相同值
​ 索引的长度不要太长(比较耗费时间)

索引什么时候失效?
记忆口诀∶模糊匹配、类型隐转、最左匹配

​ 以%开头的LIKE语句,模糊搜索
​ 出现隐式类型转换(在Python这种动态语言查询中需要注意)
​ 没有满足最左前缀原则(想想为什么是最左匹配?)

什么是聚集索引和非聚集索引?

​ 聚集还是非聚集指的是B+Tree叶节点存的是指针还是数据记录
​ MyISAM索引和数据分离,使用的是非聚集索引
​ InnoDB数据文件就是索引文件,主键索引就是聚集索引

如何排查慢查询
慢查询通常是缺少索引,索引不合理或者业务代码实现导致

​ slow_query_log_file开启并且查询慢查询日志
​ 通过explain排查索引问题
​ 调整数据修改索引;业务代码层限制不合理访问

常用表连接查询
AB
idvalidval
1ab1ab
2a3b
内连接(INNER JOIN)

​ 两个表都存在匹配时,才会返回匹配行
​ 将左表和右表能够关联起来的数据连接后返回
​ 类似于求两个表的“交集”
​ select * from A inner join B on A.id=B.id;

外连接(LEFT/RIGHT JOIN)

​ 返回一个表的行,即使另一个没有匹配

​ 外连接包含左连接和右连接
​ 左连接返回左表中所有记录,即使右表中没有匹配的记录
​ 右连接返回右表中所有记录,即使左表中没有匹配的记录
​ 没有匹配的字段会设置成NULL

全连接 (FULL JOIN)

​ 只交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。
​ 要某一个表存在匹配就返回

Redis

什么是缓存?为什么要使用缓存?

常见的内存缓存有Redis和Memcached

缓解关系数据库(常见的是Mysql)并发访问的压力︰热点数据
减少响应时间∶内存IO速度比磁盘快
提升吞吐量:Redis等内存数据库单机就可以支撑很大并发

操作时间对比

操作响应时间
打开一个网站几秒
在数据库中查询一条记录(有素引)十几毫秒
机械磁盘一次寻址定位4毫秒
从机械磁盘顺疗读取1MB 数据2毫秒
从 SSD磁盘顺序读取1MB数据0.3毫秒
从远程分布式缓存Redis 读取一个数据0.5毫秒
从内存中读取IMB数据十几微秒
Java程序本地方法调用几微秒
网络传输2KB 放据1微秒
Redis和Memcached主要区别?
对比参数RedisMemcached
类型1、支持内存
2、非关系型数据库
1、支持内存
2、key-value键值对形式
3、缓存系统
数据存储类型1、String
2、List
3、Set
4、Hash
5、Sort Set【俗称ZSet】
1、文本型
2、二进制类型【新版增加】
查询【操作】类型1、批量操作
2、事务支持【虽然是假的事务】
3、每个类型不同的CRUD
1、CRUD
2、少量的其他命令
附加功能1、发布/订阅模式
2、主从分区
3、序列化支持
4、脚本支持【Lua脚本】
1、多线程服务支持
网络IO模型1、单进程模式1、多线程、非阻塞IO模式
事件库自封装简易事件库AeEvent贵族血统的LibEvent事件库
持久化支持1、RDB
2、AOF
不支持
Redis常用数据类型和使用场景

​ String(字符串): 用来实现简单的KV键值对存储,比如计数器
​ List(链表): 实现双向链表,比如用户的关注,粉丝列表
​ Hash(哈希表): 用来存储彼此相关信息的键值对
​ Set(集合): 存储不重复元素,比如用户的关注者
​ Sorted Set(有序集合): 实时信息排行榜

Redis内置实现

​ String: 整数或者sds(Simple Dynamic String)
​ List: ziplist或者double linked list
​ Hash: ziplist或者hashtable
​ Set: intset或者hashtable
​ SortedSet: skiplist 跳跃表
​ 深入学习请参考: 《Redis设计与实现》

Redis持久化

​ 快照方式RDB(Redis DataBase):把数据快照放在磁盘二进制文件中,dump.rdb
​ AOF(Append Only File):每一个写命令追加到appendonly.aof中

Redis事务
和Mysql的事务有什么不同?

​ 将多个请求打包,一次性、按序执行多个命令的机制
​ Redis通过MULTI,EXEC,WATCH等命令实现事务功能
​ Python redis-py pipeline=conn.pipeline(transaction=True)

Redis分布式锁

​ 使用setnx实现加锁,可以同时通过expire添加超时时间
​ 锁的value值可以使用一个随机的uuid或者特定的命名
​ 释放锁的时候,通过uuid判断是否是该锁,是则执行delete释放锁

常用的缓存使用模式

​ Cache Aside:同时更新缓存和数据库
​ Read/Write Through:先更新缓存,缓存负责同步更新数据库
​ Write Behind Caching:先更新缓存,缓存定期异步更新数据库

如何解决缓存穿透问题?

大量查询不到的数据的请求落到后端数据库,数据库压力增大
​ 由于大量缓存查不到就去数据库取,数据库也没有要查的数据
​ 解决︰对于没查到返回为None的数据也缓存
​ 插入数据的时候删除相应缓存,或者设置较短的超时时间

如何解决缓存击穿问题?

某些非常热点的数据key过期,大量请求打到后端数据库
​ 热点数据key 失效导致大量请求打到数据库增加数据库压力
​ 分布式锁:获取锁的线程从数据库拉数据更新缓存,其他线程等待
​ 异步后台更新∶后台任务针对过期的key自动刷新

如何解决缓存雪崩问题?

缓存不可用或者大量缓存key同时失效,大量请求直接打到数据库
​ 多级缓存:不同级别的key设置不同的超时时间
​ 随机超时: key的超时时间随机设置,防止同时超时
​ 架构层:提升系统可用性。监控、报警完善

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值