关系型数据库是什么?
Mysql 是一个围绕着数据库表结构+行数据+索引+最后生成的crud的操作的集合
age字段添加索引,就你可以通过索引快速找到所属的值
存储引擎?
InnoDB和MISAM
1:InnoDB支持事务,MyISAM不支持(因为它没有向InnoDB的 undo log / redo log做一个事务的回滚 事务的提交 以及事务的控制补偿)
2:InnoDB 支持外键(大多企业为了严谨性使用的外键约束,有的企业则使用的逻辑外键去达成业务需求),而MyISAM不支持
3:InnoDB 聚集索引(查找到索引的位置 相当于查询到数据),而MyISAM是非聚集索引(查找到索引的位置 只是告诉你 索引在哪儿,还要多经过一跳的路移位找到数据的本身, 非聚集索引的value 存储的是数据的地址)
4:InnoDB 支持表,行(默认)级锁,而MyISAM支持表级锁(MyISAM优势是数据分析和处理 但是这个一般是 spark 和 hoodup去)
所以InnoDB是最佳选择......
事务的隔离级别?
脏读:读到了一个 未提交的事务数据
例如:用户购买商品,还正在处于付钱的状态, 但是就已经把对方钱扣除了,
下图 事务A在发起一个修改的事件,但是还没有提交commit,或者在提交的时候 网络中断了,事务回滚了, 这时候事务B依然读取到了 事务A未提交的 test1数据...
读已提交如何解决脏读?
当事务A完全commit 提交以后 事务B才能读到test1 这个信息
在读已提交下面 不可能做到: (不可重复读)
可重复读(解决不可重复读)
可重复读, 当事务B 执行事务 sql1 读取id=1的数据时候 命中id=1这条数据上,并且查询发现 name=test,这时候 事务B就会记录下一个版本号,意思就是 读取对应这条记录的版本,我们把它可以理解为 mysql 当中mvcc多版本控制 快照 版本的概念...
同一个事务下 是可以重复读的,因为例如事务B执行sql1 以后 会命中记录当前的版本号, 当再次去查询同一条数据的时候, 因为mvcc 这个多版本控制 做了一个版本缓存的记录,以此才能满足 事务B多次查询 是否满足命中版本.
当同一个事务,第一次执行事务查询以后,记录版本号,那么后续查询相同值 都会去命中 同一个数据结果
幻读?
同一个事务 在两次读取的过程当中,读取到的数据条数 是有变化的...
下图在事务B 执行第一条sql的时候, 事务Acommit 还没有执行,表里已经添加过id=2的数据了, 这时候查询是二条数据, 当执行delete以后 commit 提交了 ,事务B 第二条sql 就只能查询一条数据
串行化?
串行化的隔离级别下,所有的内容,所有的事务,都是串行化的,自然就不存在 脏读,不可重复读和幻读这种并发的情况下才会发现的这样一个问题...
快照度和当前读?
快照读还是当前读 都可以完美的去解决事务隔离级别的一些问题
快照读利用MVCC 读快照,用空间去换时间 读取一个对应老的版本
当前读直接采用加锁 串行化的方式 保证对应数据的一个一致性 和完整性....
、
快照读:通过mvcc這樣一个机制 做了一个多版本控制
当前读 :需要一个争夺锁的过程, 这个锁的话 可能是,用主键或者唯一索引 去锁的一个行记录的行锁,又或者是对非唯一索引去加一个行锁+间隙锁这种过程, 没有索引的情况下 就会升级为表锁....
索引相关?
在mysql 当中 使用的是B+树去存储索引(B+树为矮胖形)
**假设根节点为:10 **
<10的会存存左边 相反右边
下图叶子节点之间还有 对应的兄弟指针对应连接, 方便磁盘范围的查找,以及一个对应的 顺序IO的过程
聚簇索引/非聚簇索引
只能有一个聚集索引,但是可以有多个非聚集索引;
例如:主键索引==聚簇索引, 多个非主键索引/非主键索引==非聚簇索引
主键索引(聚簇索引),为什么查询快呢; 因为数据的本身就是存储在主键索引上面的
非聚簇索引对应的是数据存储的地址,所以在查询的时候是先去找到地址然后一跳再去查询数据本身
非聚簇索引唯一的 称为:唯一索引, 反之为 : 非唯一索引 唯一索引查询速度>非唯一索引
创建索引的注意点:
当sql 有and 时候 必须符合最左匹配原则,
**有order by 的条件的时候 最好使用联合索引, 尽可能去避免 file sort **
如果我们在查询数据 经常需要回表操作的话,那我们尽可能要使用 覆盖索引
如果order by 后面有字段条件
这时候就需要做一个 联合索引 查询, 尽可能避免file sort
如果这个语句后面跟着 范围limit 查询,就需要在返回列上 修改为 对应索引返回的字段,防止回表查询 这就是status+age的 覆盖索引, 当数据量 大的时候 回表操作 是不可忽视的(回表操作就是,返回的列 存在着 非索引字段,就会造成回表操作)
日志相关?
事务日志过程
WAF机制
刷盘时机 (
1:每次commit 就去刷盘(安全 )
2:每次将数据写到内存,每秒做一次刷盘 (对应的应用程序进程内存缓冲,进程挂掉,那么久没有了)
3:每次将数据写到磁盘缓冲内,每秒去刷盘(mysql 宕机,操作系统还活着 就没事,任然可以被刷到磁盘空间内)
)
当mysql 收到事务的请求时候,它会有开启事务这个过程,会向redo undo里面记录开启事务的行为
undo log 对应insert 操作是就 删除, redo log是这个insert 本身
对于update redo log 就是对应的一个新值 ,undo log 就是update 对于数据 把它变为一个旧的值
delete 对于redo log 就是delete 本身, undo log 就是insert 操作
所有的操作是 先记录一个日志 然后再去对数据进行改变,当commit 以后 我们就会把 磁盘内的数据刷新到 内存当中,
WAF机制: mysql 有自己的机制去把 所有磁盘 更改的脏页内容 去刷到数据库当中,当数据库发生异常重启 中断的时候,我们只需要在mysql 重启的时候 去查看redo undo日志当中 是rollback 还是 commit ,这样就可以去做事务的回滚 或者 提交的操作了....这就是mysql 高效的原因..
undo 和 redo 也不是每次都能写入磁盘内, 写到磁盘内 会有一个性能的优化.每次写入磁盘 都是顺序写入,这样性能最高,
也不是每次commit 以后就把 redo undo日志刷进去, mysql提供了几次刷盘的选择:
1:每次commit 就去刷盘(安全 )
2:每次将数据写到内存,每秒做一次刷盘 (对应的应用程序进程内存缓冲,进程挂掉,那么久没有了)
3:每次将数据写到磁盘缓冲内,每秒去刷盘(mysql 宕机,操作系统还活着 就没事,任然可以被刷到磁盘空间内)
close / flush
,
MySQL 主从分布式?
这样就保证slave 和 master 节点是一致的...
由于上述 master 和 slave 写读 操作是异步的, 例如master 事务提交以后, 还没有同步到slave上面,这时候slave 读取的数据 就不是最新的数据,
如何解决主从不一致问题:
1:通过应用层,业务层去避免,(例如 页面出现中转倒数 秒数,让用户等待主从同步的一个过程,当然也并不是 完全靠谱的....因为各种原因 延迟影响, 还可以加入监控手段,例如binlog 是有序号的,例如master 和 slave 在同一时间段 序号相差很大 例如相差10 可以就是 相差了 10个事务)
2:直接读主库,(手动去修改 读操作的服务路由,把读操作 迁移到 主库上,当然 主库 读更多 ,主从就没有意义了)
3:使用半同步机制(semi sync)跟业务无关,主要去 保证最终一致性,(用于主从切换场景,当主库出现问题宕机以后,所以必须保证 有一台slave 跟主库必须一致)
例如业务允许 有脏读的话, 就可以把读 放在slave上面,
不允许有脏读的话,手动去修改 读操作的服务路由,把读操作 迁移到 主库上master当中
如果主从压力特别大 负载太高怎么办?
分库分表?
待更新
Redis数据结构?
Stirng,hash,list.set,zset 结构图
string , hash
list
set 无序不重复
zset
zset 跳表操作:
跳表的本质作用是 用空间换时间的设计思想, 做跨区域维度的一个二级索引,然后针对这个二级索引,可以非常快速的找到某一个断区间,更加细化的去找 下一个跳表,或者说更加细化的去遍历元素的本身, 所以zset 可以让我们快速的去查找自己想要的一个内容
hash 是基于hash槽 做一个内部key value对, 这样的数据结构
list是 链表式的数据机构
set是无序不重复的集合 ,在添加数据的时候,如果集合内有相同值 返回0, 未有值 返回1
zset是一个有顺序的链表,可以帮助我们更加快速的去查询数据,可以有跳表的操作,可以自定义score 去做 排行榜这样的功能
Redis缓存?
数据持久化
rdb / aof
redis rdb文件负责记录key value的值
数据持久化方案一般需要结合: 全量数据备份(rdb)+增量数据备份(aof)组合的一个文件,
对于aof来说一般为了性能考虑 会产生以下二种情况:
1:秒刷新磁盘策略,写入redis内部,每隔一秒做aof文件持久化,
2:量刷新磁盘策略:900次更新操作做持久化
当aof到达一定阈值的时候,aof就会和之前的rdb文件合并 重新生成更大的rdb文件,这样就可以保证aof量一直在 较小的级别....
Redis集群方式?
单机,主从,哨兵,集群proxy,集群cluster
redis单机结构图 :
因为单机不好突破性能,例如CPU,资源池都不好去扩展.
下图为redis 主从结构图
主从复制的协议
master 和 slave 通过 rdb文件来 同步数据的情况.rdb的包会被同步到slave上面,slave会进行一次事务回放,然后slave 和 master 就是一模一样的
哨兵结构图:
sentinal主要是去监控 master 和slave的存活状态的
redis client 启动会主动去sentinal读取master 和 slave 数据
通过sentinal 才知道 set 是在master上面 get在slave上
当主机出现宕机 中断, sentinal会主动 主从切换,
切换以后 sentinal 也会主动通知client 修改对应 get set 主从位置
在主从这里, 可以一主一从,一主多从,多主多从
版权归原作者 是汤圆丫 所有, 如有侵权,请联系我们删除。