数据库相关知识整理(更新中)

事务及事务的四大特征

1、事务

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

2、事务四大特征

  • A:原子性(Atomicity) 事务操作要么完成,要么不完成,执行过程发生错误会回滚。
  • C:一致性(Correspondence) 事务前后数据库完整性、约束性没被破坏。如完整性约束a+b=10,若a变,必须改变b保证a+b=10。
  • I:隔离性(Isolation) 隔离状态执行事务,确保每一事务在系统中认为只有该事务在使用系统,事务的串行化,这个主要是关于事务并发的概念。
  • D:持久性(Durability) 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

关系型数据库、非关系型数据库简介、区别

  • 关系型数据库:指采用了关系模型(如mysql表)来组织数据的数据库。
    存在的问题:
    (1)网站的用户并发性非常高,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈.
    (2)数据库的横向扩展难度较大,当需要对数据库系统进行升级和扩展时,往往需要停机维护和数据迁移。
    (3)ACID特性导致设计以及关联查询有一定难度。

  • 非关系型数据库:以键值对存储,且结构不固定,分布式,且**一般不保证遵循ACID原则的数据存储系统。**非关系型数据库严格上来说是一种数据结构化存储方法的集合。

  • 两类代表:redis与mysql,为什么redis比mysql快?
    (1) Redis存储的是k-v格式的数据。绝大部分操作(MGET是O(N))复杂度O(1),而MySQL引擎的底层实现是B+Tree,时间复杂度是O(logn)。
    (2) MySql基于磁盘存储,redis基于内存,读写速度差别大。

MySql的索引

Alt

  • 索引就是为了加快查找而引入的数据结构。在MySql中有两种实现方式:B+树和hash。

  • 采用B+(innoDB和MyISAM都用b+)的原因:一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。评价数据结构作为索引的优劣性指标就是磁盘I/O。B+相较于红黑树节点层数少,相较于B树只有叶子节点存有data域,且链表维护最后一层叶子节点,方便查找全部数据。mongoDB用B树。

  • 为什么说B+树比B树更适合做操作系统的数据库索引和文件索引?
    (1)B+树的磁盘读写的代价更低
    B+树内部结点没有指向关键字具体信息的指针,这样内部结点相对B树更小。
    (2)B+树的查询更加的稳定
    因为非终端结点并不是最终指向文件内容的结点,仅仅是作为叶子结点中关键字的索引。这样所有的关键字的查找都会走一条从根结点到叶子结点的路径。所有的关键字查询长度都是相同的,查询效率相当。

  • 哈希索引,是根据索引的键值计算出响应的hash值,然后根据hash表中的地址来定位数据。效率较高,可一次定位,不像B+树索引要从根节点到枝节点。但是(1)hash索引只能用于“=”“IN”“<=>(严格比较两个NULL值是否相等,相等为1,否则为0)”查询,不能使用范围查询。(2)同理,由于哈希索引中存放的是键值经过哈希运算后的hash值,不保留键值大小关系,所以无法用索引避免排序运算。 (3)不同键值索引存在相同的hash值,不可避免对表进行扫描。

聚集索引与非聚集索引

  • (主键索引)聚集索引:数据行的物理顺序与列值的逻辑顺序相同。非聚集索引存在二次查询为题,且非聚集索引不唯一。
  • 聚集索引插入数据时速度要慢(时间花费在“物理存储的排序”上,也就是首先要找到位置然后插入),查询数据比非聚集数据的速度快。
  • B+树中只有叶子节点会带有指向记录的指针,而B树则所有节点都带有。
  • B+树索引可以分为聚集索引和非聚集索引。
  • mysql使用B+树,其中Myisam是非聚集索引,innoDB是聚集索引
  • 聚集索引的叶节点就是数据节点;而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。(二次查询)
    在这里插入图片描述
    InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。

Mysql Innodb中的索引数据结构是 B+ 树,普通索引,也叫做辅助索引,叶子节点存放的是主键值。主键上的索引叫做聚集索引,表里的每一条记录都存放在主键的叶子节点上。
唯一索引本质上是辅助索引,然后加了唯一约束。

————————————————
在这里插入图片描述

MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

MySql最左前缀匹配原则

在MySQL建立联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。

abrowid
121
132
3
22256

创建一个索引

 create index index_1 on t(a,b)

当 select * from T where a = 1 and b = 2的时候, 数据库系统可以直接从索引文件中直接二分法找到 A = 1 的记录,然后再 b = 2 的记录。但如果直接where b = 2 则需要遍历这个索引表的全部(索引失效)。

MySql数据库的优化

  • 选取合适的字段属性,如邮政编码字段char(6)与char(255)的比较。
  • 使用join代替子查询。
  • 用UNION代替手动创建的临时表
  • 建立索引,一般,索引应建立在那些将用于JOIN,WHERE判断和ORDER BY排序的字段上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。
  • NOT IN操作会扫描全表,尽量避免使用
  • 应尽量避免在 where 子句中对字段进行 null 值判断、使用>、<、=操作符、or连接条件,否则将导致引擎放弃使用索引而进行全表扫描。

索引失效情况:

  • like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。
  • or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效
  • 组合索引,不是使用第一列索引,索引失效。
  • 数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描。
  • 在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 优化方法: key<>0 改为 key>0 or key<0。
  • 当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效。

MySql事务的并发和事务隔离级别

https://www.pianshen.com/article/7321786855/ 这篇文章图画的不错

  • 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。
  • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
  • 幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。不可重复读侧重于修改,幻读侧重于新增或删除

MySql事务隔离级别
mysql默认隔离级别为可重复读。

  • 脏读,事务B修改后,还没正式提交前,事务A就已经读到修改内容了
    读未提交

  • 不可重复读,事务B修改多次内容且提交后,事务A在多次读的过程中发现每一次读到的都不一样。

  • 幻读

  • 在这里插入图片描述

Redis持久化

Redis是一个内存数据库数据保存在内存中**(不同于mysql,mysql是持久化储存,放在磁盘里)**,由于内存的数据变化是很快,容易发生丢失。Redis还为我们提供了持久化的机制,分别是RDB(Redis DataBase)和AOF(Append Only File)

  • RDB:
    RDB其实就是把数据以快照的形式保存在磁盘上。RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
    RDB优势:(1)RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
    (2)生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
    (3)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
    RDB劣势:在快照持久化期间修改数据可能容易导致数据丢失。

  • AOF机制:全量备份总是耗时的,有时候我们提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录

  • 在这里插入图片描述
    每当有一个写命令过来时,就直接保存在我们的AOF文件中。
    AOF优点:AOF可以更好的保护数据不丢失,即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
    缺点:对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大
    在这里插入图片描述

单线程redis

Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行。并且多个客户端发送的命令的执行顺序是不确定的。但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。

(1) 绝大部分请求是纯粹的内存操作(非常快速)

(2) 采用单线程,避免了不必要的上下文切换和竞争条件

(3) 非阻塞IO - IO多路复用,Redis采用epoll做为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为了时间,不在I/O上浪费过多的时间。

…更新中,如有相关建议,欢迎您提出,谢谢。

Redis高并发原理

(1)纯内存访问。数据存放在内存中,内存的响应时间大约是100纳秒,这是Redis每秒万亿级别访问的重要基础。

(2)非阻塞I/O,Redis采用epoll做为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为了事件,不在I/O上浪费过多的时间。

(3)单线程避免了线程切换和竞态产生的消耗。

注意 在创建请求(建立连接请求)以及返回结果不一定是单线程。执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行

https://zhuanlan.zhihu.com/p/91539644

待看 https://www.cnblogs.com/jack1995/p/10914058.html

Redis类型

  • string:做简单的kv缓存

  • hash : hash是一个string类型的field和value的映射表,hash特别适合用于存储对象(应为对象可能会包含很多属性)

  • list : 字符串列表,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。

  • set : 集合,差、并、交集操作,全局去重

  • sorted set : 有序集合,排行榜,用户列表,内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,跳跃表按score从小到大保存所有集合元素。使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。时间复杂度与红黑树相同,增加、删除的操作较为简单。如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员是比较长的字符串(字符串长占内存,原始链表中存储的有可能是很大的对象,而索引结点只需要存储关键值值和几个指针,并不需要存储对象)时, Redis就会使用跳跃表来作为有序集合健的底层实现。

  • 功能:作为***缓存***,配合其它数据库作为存储层,利用Redis支持高并发的特点,可以大大加快系统的读写速度、以及降低后端数据库的压力。

redis淘汰策略

当Redis的内存(maxmemory参数配置)已满时,它会根据淘汰策略(maxmemory-policy参数配置)进行相应的操作。

  • 不删除策略(no-eviction) 达到最大内存限制直接报错
  • lru
  • lfu
  • random 随机删除一部分key

redis删除策略

Redis是 key-value 数据库,可以设置Redis缓存的key的过期时间。Redis的过期删除策略就是指当Redis中的key过期了,Redis是如何进行处理的。

  • 定时删除 : 在设置key的过期时间的同时,Redis会创建一个定时器,当key达到过期时间时,立即删除该键。
  • 惰性删除: 放任键过期不管,只有当获取键时,才检查获取的键是否过期,若过期删除该键;若没过期,就返回值。
  • 定期删除: 每隔一段时间(默认100ms),程序就对数据库进行一次检查,删除过期键。

redis采用的定期删除和惰性删除

Redis线程模型

在这里插入图片描述
基于reactor模式,因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。

Redis异常

  • 缓存雪崩:同一时间内大量键过期(失效),导致所有请求瞬间都落在了数据库中导致连接异常而崩掉
    如何解决缓存雪崩

给缓存数据的过期时间设置随机机,防止同一时间大量数据过期。
给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,若标记失效,则更新缓存数据。
并发量不大时,可以使用加锁排队。

对于"Redis挂掉了,请求全部走数据库"这种情况,我们可以有以下的思路:
事发前:实现Redis的高可用(主从架构+Sentinel或者Redis集群),尽量避免Redis挂掉
事发中:设置本地缓存(ehcache)+限流(hystrix),尽量避免数据挂掉,保证服务能正常工作
事发后:redis持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据

  • 缓存穿透:恶意请求缓存中不存在的数据,导致所有请求都落在数据库,造成短时间承受大量请求而崩掉。
    可以考虑通过把可能的数据哈希到bitmap拦截。

  • 缓存击穿:并发查询同一条缓存中没有但是数据库有的数据
    可通过设置热点数据用不过期来解决。
    利用互斥锁:在缓存失效的时,先获取锁,得到锁后再去请求数据库。没有得到锁,则休眠一段时间在重试。

MySQL、MongoDB、Redis 数据库之间的区别

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值