关系型数据库是什么?
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数据...
读已提交如何解决脏读?
在读已提交下面 不可能做到: (不可重复读)
可重复读(解决不可重复读)
同一个事务下 是可以重复读的,因为例如事务B执行sql1 以后 会命中记录当前的版本号, 当再次去查询同一条数据的时候, 因为mvcc 这个多版本控制 做了一个版本缓存的记录,以此才能满足 事务B多次查询 是否满足命中版本.
当同一个事务,第一次执行事务查询以后,记录版本号,那么后续查询相同值 都会去命中 同一个数据结果
幻读?
下图在事务B 执行第一条sql的时候, 事务Acommit 还没有执行,表里已经添加过id=2的数据了, 这时候查询是二条数据, 当执行delete以后 commit 提交了 ,事务B 第二条sql 就只能查询一条数据
串行化?
快照度和当前读?
、
索引相关?
在mysql 当中 使用的是B+树去存储索引(B+树为矮胖形)
假设根节点为:10
<10的会存存左边 相反右边
下图叶子节点之间还有 对应的兄弟指针对应连接, 方便磁盘范围的查找,以及一个对应的 顺序IO的过程
聚簇索引/非聚簇索引
只能有一个聚集索引,但是可以有多个非聚集索引;
例如:主键索引==聚簇索引, 多个非主键索引/非主键索引==非聚簇索引
主键索引(聚簇索引),为什么查询快呢; 因为数据的本身就是存储在主键索引上面的
非聚簇索引对应的是数据存储的地址,所以在查询的时候是先去找到地址然后一跳再去查询数据本身
非聚簇索引唯一的 称为:唯一索引, 反之为 : 非唯一索引 唯一索引查询速度>非唯一索引
创建索引的注意点:
当sql 有and 时候 必须符合最左匹配原则,
有order by 的条件的时候 最好使用联合索引, 尽可能去避免 file sort
如果我们在查询数据 经常需要回表操作的话,那我们尽可能要使用 覆盖索引
如果order by 后面有字段条件
这时候就需要做一个 联合索引 查询, 尽可能避免file sort
如果这个语句后面跟着 范围limit 查询,就需要在返回列上 修改为 对应索引返回的字段,防止回表查询 这就是status+age的 覆盖索引, 当数据量 大的时候 回表操作 是不可忽视的(回表操作就是,返回的列 存在着 非索引字段,就会造成回表操作)
日志相关?
当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提供了几次刷盘的选择:
,
MySQL 主从分布式?
这样就保证slave 和 master 节点是一致的...
由于上述 master 和 slave 写读 操作是异步的, 例如master 事务提交以后, 还没有同步到slave上面,这时候slave 读取的数据 就不是最新的数据,
如何解决主从不一致问题:
1:通过应用层,业务层去避免,(例如 页面出现中转倒数 秒数,让用户等待主从同步的一个过程,当然也并不是 完全靠谱的....因为各种原因 延迟影响, 还可以加入监控手段,例如binlog 是有序号的,例如master 和 slave 在同一时间段 序号相差很大 例如相差10 可以就是 相差了 10个事务)
2:直接读主库,(手动去修改 读操作的服务路由,把读操作 迁移到 主库上,当然 主库 读更多 ,主从就没有意义了)
3:使用半同步机制(semi sync)跟业务无关,主要去 保证最终一致性,(用于主从切换场景,当主库出现问题宕机以后,所以必须保证 有一台slave 跟主库必须一致)
如果主从压力特别大 负载太高怎么办?
分库分表?
待更新
Redis数据结构?
Stirng,hash,list.set,zset 结构图
string , hash
list
set 无序不重复
zset
zset 跳表操作:
跳表的本质作用是 用空间换时间的设计思想, 做跨区域维度的一个二级索引,然后针对这个二级索引,可以非常快速的找到某一个断区间,更加细化的去找 下一个跳表,或者说更加细化的去遍历元素的本身, 所以zset 可以让我们快速的去查找自己想要的一个内容
Redis缓存?
数据持久化
rdb / aof
redis rdb文件负责记录key value的值
数据持久化方案一般需要结合: 全量数据备份(rdb)+增量数据备份(aof)组合的一个文件,
对于aof来说一般为了性能考虑 会产生以下二种情况:
当aof到达一定阈值的时候,aof就会和之前的rdb文件合并 重新生成更大的rdb文件,这样就可以保证aof量一直在 较小的级别....
Redis集群方式?
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 主从位置