关系型数据库是什么?
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? 主从位置?
在主从这里, 可以一主一从,一主多从,
redis client? 可以有? 多主多从(一个master 对应 一个 slave 也对应一个哨兵)?
?
集群proxy代理?
proxy+注冊中心+多主多从
zk负责 监控 多服务的节点,数据master? /slave? 状态的感知
proxy 通过zk 获取
?
redis缓存/淘汰机制
redis单线程模型
?
?
|