聚集索引和非聚集索引?
聚集索引:索引值和数据是存在一起的
非聚集索引:索引值和数据不是存在一起的
存储引擎是innoDB,主键上的索引是聚集索引,二级索引/辅助索引是非聚集索引
存储引擎是MyISAM,都是非聚集索引
innoDB:索引和数据存在一个文件里,表结构存在一个文件里
myIRAM:索引,数据,表结构分别存储在一个文件里
二级索引/辅助索引?
属于非聚集索引,所有非主键索引都是二级索引,二级索引叶子节点存的是主键值,查数据的话需要两次IO,需要回表(避免回表,避免使用select *)
覆盖索引?
覆盖索引不需要回表,select后查的字段是被我们建立的复合索引所覆盖的。
索引下推?
优化的方式,减少回表的次数,减少回表查询的行数,不需要我们开发人员干涉,mysql优化器处理,减少IO以及回表
id,name,age,city三个字段,city和age是复合索引,select * from user where age>15 and city='大同’的在二级索引层面对数据就进行过滤了,然后回表,减少io,如果只给age加索引,city没有加索引的话,age>15的查询一次,回表到主键索引里查出age大于15的再过滤city='大同’的,这样io的行数会很多。索引下推减少io次数以及减少回表查询的行数。
索引失效的情况?
1,索引字段参加运算,索引失效
2,索引字段模糊查询以%开头,索引失效
3,索引字段是字符串(char),where条件后要加单引号,不加索引失效
4,查询条件使用or(有非索引字段,索引就会失效)
5,索引字段使用 is null,is not null 索引失效
6,表中数据查询,符合索引条件的数据比重大,索引会失效
explain
查询select语句的执行计划
RDB和AOF?(redis数据持久化)
RDB文件里存的缓存的数据
AOF文件里存的是写命令
mysql的ACID原理
原子性,一致性,隔离性,持久性
undo Log是实现原子性的一个原理(里边记录我们执行sql语句相反操作的语句,用于回滚)
redo Log是实现持久性的原理(追加的方式将数据写入redo Log用于持久化数据)
隔离性 写写是加锁 读写是通过mvcc
什么是事务
事务是一个最小的工作单元,不可再分。
JVM的双亲委派机制?
双亲委派机制是一种类加载机制,目的是确保类的唯一性和安全性,当JVM加载一个类时,会将加载请求委派给父类加载器,如果父类加载器无法加载该类时会继续向上委派,直到委派给启动类加载器,如果启动类加载器也无法加载,则由当前类加载器加载,避免了类的重复加载,确保类的全局唯一性,同时也保护了程序的安全,防止核心的API被随意篡改。
自定义类加载器->应用程序类加载器->扩展类加载器->启动类加载器
如何打破双亲委派机制?
当前读和快照读
普通的select语句是快照读,select…for update 是当前读会对数据加锁(增,删,改,操作之前都会进行一次当前读)
读未提交,读已提交,可重复读,串行化
读未提交存在脏读,幻读,不可重复读
读已提交存在幻读,不可重复读
可重复读部分情况存在幻读
可重复读在什么情况下出现幻读?
开启事务,普通select是快照读,完了之后执行增,删,改,之后会出现幻读
避免幻读:要么都用快照读,要么都用当前读
记录锁,间隙锁
4,5,8
select * from t_user where id between 4 and 8 for update;
记录锁这三条数据删不了,等待另一个事务提交后才能删除,间隙锁这中间的数据插不进去,等待另一个事务提交后新增
记录锁防删除 间隙锁防插入的
可重复读隔离级别下如何解决幻读?(老杜)
快照读如何解决幻读?
MVCC机制
实现的方式是开始事务后,在执行第一个查询语句后,会创建一个Read View ,后序的查询语句利用这个Read View ,通过这个Read View 就可以在undo Log 版本链找到事务开始时的数据,所以事务过程中每次查询的数据都是一样的,即使中途有其他事务插入新记录,是查询不出来这条数据的,所以就很好的避免了幻读问题
当前读如何解决幻读?
加锁的方式避免幻读(间隙锁,记录锁)
MVCC(黑马)
多版本并发控制,是指维护一个数据的多个版本,使得读写没有冲突,快照读为mysql实现mvcc提供了非阻塞读的功能,mvcc实现需要依赖于数据库记录中的三个隐式字段,undoLog,readView
数据库的三个隐藏字段?
1,事务id(自增) 2,主键 3,回滚指针(指向记录(undo Log)的数据的上一个版本)
undo Log日志:在增,删,改的时候产生便于数据回滚
在新增的时候,产生的undo Log日志只在回滚时需要,事务提交后可被立即删除
而删除,修改的时候,产生的undo Log日志不仅回滚时需要,在快照读的时候也需要,不会立即删除
undo Log版本链
readView读视图
不同隔离级别生成readView的时机不同,读已提交(每一次执行快照读都会生成readView),可重复读(只在开启事务第一个快照读生成readView后序复用该readView)
作用是:在快照读的时候决定我们读的是哪个记录版本
mvcc+锁决定了数据库的隔离性
redoLog,undoLog决定一致性
接口幂等性解决方案
1,setNx 商品id+用户id设置为key(一人下一单业务)
2,token+redis :进入页面后请求token接口获取token(存在redis用setNx),页面请求时带着token,执行第一次,判断是否存在,存在的话删除token并执行之后的业务代码(注册业务)
3,利用数据库的唯一索引,设置幂等字段(加唯一索引)
4,update也会存在幂等性问题 加乐观锁,类似于版本号
char和varchar的区别
char定长 varchar变长
redo Log 和undo Log ?
redo Log 重做日志 (保证事务的持久性,用于数据恢复,记录对数据库的物理修改,记录的是数据)两部分组成 redo Log buffer 和redo Log file
buffer是存在内存 file存在于磁盘
undo Log 回滚日志 (保证事务的原子性,提供回滚,记录的是对数据库操作的相反操作语句),
binLog二进制日志
记录表中增,删,改的操作语句,主从复制用到binLog
缓存和数据库数据一致性的解决方案
先更新数据库,再删除缓存
主从复制架构下如何保证数据一致性,需要一个订阅二进制日志系统比如阿里的canal,去订阅主数据库二进制日志的变化,有变化后就刷新二进制日志并且更新redis这样就实现缓存与数据库数据一致的问题了,还可以引入mq,如果cannal中更新数据库的操作,将更新redis的数据发送给mq,如果网络原因cannel更新到redis失败,可以利用mq的重试机制。