天天看点

数据库Mysql的(脏读、幻读、虚读、不可重复读、MVCC、MST、回表、索引覆盖、最左匹配、索引下推、聚簇索引)这些名词都是什么意思?

  • 读未提交:一个事务可以读取到其他事务没有提交的数据,即脏读。
  • 读已提交:一个事务只能读取到其他事务已经提交的最新数据。可能导致多次读取的结果不一致,即不可重复读
  • 可重复读:一个事务只能读取到其他事务已经提交的数据,且多次读取结果一致。其实现原理为事务开启时即锁定一个读取版本,而不是每次读取都读最新的版本。但这个只是避免了其他事务修改已有的数据,如果查询语句是区间查询,则无法避免其他事务新增数据,可能导致多次读取数据行数不一致,即幻读
  • 串行化:多个事务之间串行化执行,虽然没有任何问题,但是效率很低,一般不用。
  • MVCC:全称Multi-Version Concurrency Control,即多版本并发控制。我们来想一个场景,A事务读取数据的时候,B事务在写数据,如何避免A事务读取数据读取到B事务的半写或者不一致的数据呢?常用的办法是A事务等待B事务写完毕之后再读,但这样效率太低了。MVCC的方式即B事务写数据的时候不在原来的数据上修改,而是把原来的数据版本标记为过时,同时新启一个版本来写自己的数据。而A事务读的时候一直是读的前面那个老的版本,此方式虽然可以并发读写,但是会引发幻读/虚读的问题。
  • MST:全称Multi-Threaded Slaves,即并行复制或多线程复制。我还没搞懂如何用通俗的几句话把这个东西说清楚,只知道这个东西因为是并行复制,貌似可以加快主从数据库同步。欢迎评论区指正。
  • 回表:Mysql的InnoDB中,如果我们创建的索引是组合索引,比如一张表有(id, name, age, addr)这几例,我们对name, age列建立了联合索引,而我们的查询语句是​

    ​select addr from t where name='张三' and age=20​

    ​​就会去回表,为什么呢?因为联合索引索引中只是存储了索引列和id的值,但我们查询的是addr,所以需要用找到了id继续去主键索引中回查一次,这个过程就叫索引,如果我们的语句是​

    ​select name from t where name='张三' and age=20​

    ​,那么就不需要回表,因为索引中已经包含了name的值。
  • 索引覆盖:所谓索引覆盖,就是说一条语句有没有用到索引,用到了就说覆盖到了,反之则是未覆盖。
  • 最左匹配:我们还是以上诉例子为例:一张表有(id, name, age, addr)这几例,我们对name, age列建立了联合索引。由于name在age之前,所以我们如果查询语句是​

    ​select * from t where name = '张三'​

    ​​这条语句是会走索引的,而如果是​

    ​select * from t where age = 20​

    ​这条语句是不会走索引的,这就是常说的最左匹配原则。
  • 索引下推:我们还是以上诉例子为例:一张表有(id, name, age, addr)这几例,我们对name, age列建立了联合索引。如果我们执行语句​

    ​select * from t where name like '张%' and age=20​

    ​​这条语句,在mysql5.6之前,mysql的执行逻辑是先查询出数据中所有name为张开头的数据,然后再根据age=20这个条件来过滤,在mysql5.6之后,会同时使用​

    ​name like '张%' and age=20​

    ​这两个条件来过滤,大大提升了查询的效率。
  • 聚簇索引:聚簇索引和非聚簇索引即数据和索引是否分开,在InnoDB的主键索引中,数据是存在索引树里面的,所以叫聚簇索引,而在MyISAM中,索引树中只是存储数据的行号,所以叫非聚簇索引