CPPInterview

数据库原理

联合索引

B树

不同隔离级别存在的问题

  1. 脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的
  2. 不可重复读(Unrepeatable read): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读
  3. 幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。

左右联接

主键

explain 查看执行计划

聚簇索引

MySQL优化

read view

行锁

MVCC

平衡树和红黑树的区别

共享锁和排它锁

行锁和表锁讲解

select * from user;
select ... lock in share mode;
select ... for share;  MySQL 8.0
update ...
delete ...
insert ...
select ... for update

分库分表

垂直分表:一个表,列比较多,把不同的字段分到不同的表中,降低单表大小来提高性能。 水平分表:以某个字段按照一定的规则,将一个表的数据分到多个表中。特点是表结构一样。 分表策略

左右联接

学习视频

联接练习题

alter table 表名 alter column 字段名 set default 默认值;

开启事务

关键字

数据库优化

Mysql主从复制和读写分离

读写分离存在的问题:

视频辅助

索引失效

  1. 范围查询后其右边的列,索引失效。即索引某个字段使用了范围查询,他右边的索引将不再走索引。
  2. 在索引列上进行运算操作,索引失效。(子串匹配查询)
  3. 字符串不加单引号,索引失效。
  4. 用or分割的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。
  5. 以%开头的like模糊查询,索引失效。
  6. 如果mysql评估全表扫描更快,索引失效。
  7. is NULL, is NOT NULL, 有时索引失效。
  8. in走索引,而not in索引失效。

优化

  1. 使用索引。
  2. 根据sql实际解析的顺序,调整索引的顺序。
  3. 尽量使用覆盖索引,避免select。覆盖索引是指只出现在索引中的字段。
  4. 尽量使用复合索引,而少使用单列索引。
  5. 优化insert。一次插入多条数据。事务改为手动提交,分段提交。按主键顺序插入。
  6. 优化order by尽量使用using index 而避免使用filesort

定位低效sql语句

  1. explain分析执行计划(索引失效或者关联查询太多join)
  2. 慢查询日志
  3. show profiles

mysql分库分表

视频辅助

主从集群也就是读写分离,读写分离只是分担了访问的压力,存储的压力并没有解决。数据库集群环境后都是多台slave,基本满足了读取操作,但是频繁写入堆master性能影响比较大,这个时候,单库并不能解决大规模并发写入的问题。

分库分表带来的问题:1. 联合查询问题,join不再适用。2.事务问题,变成了分布式事务。好处:减少大量数据写入时锁对查询的影响。按照存储类别分:用户库,业务库,内存库,图片库,日志库,统计库。

分表:垂直分表和水平分表。解决单张表记录太多的问题。切分策略和导航路由。单表的容量超过500W时建议水平拆分。不到最后一步,不要轻易进行水平分表。

开源方案:1. msyql fabric 2.atlas 3.TDDL 4.mysql proxy 小巧精干,能力有限。+ master/slave 构成一个简单版的读写分离和负载均衡。

主从复制,读写分离—> 垂直分库(每个库可以带slave)—>分区—->水平分表。中间各种通信,调度,维护和编码要求更高。

主从复制

一主多从。 mysql复制是异步并串行化的。原理:slave从master读取binlog进行数据同步。主要分为3步:

  1. master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件binary log events。
  2. slave从master的binary log events拷贝到它的中继日志relay log
  3. 重做中继日志中的事件,将改变应用到自己的数据库中。

锁机制

锁可以对有限的资源进行保护,解决隔离和并发的矛盾。通过锁机制可以实现事务的隔离性要求,使得事务可以并发地工作。

按操作分:读锁(共享锁) 写锁(排他锁)

按粒度分:行锁(偏写)表锁(偏读)

锁使用的考虑点:开销,加锁速度,死锁,粒度,并发性能。

行锁:innoDB 开销大,加锁慢,会出现死锁,粒度小,锁冲突概率低,并发高。

表锁:myisam 开销小,加锁快,无死锁,粒度大,锁冲突概率高,并发性低。

行锁的三种算法:1. record lock 2.gap lock 3. next-key lock

锁带来的三种问题:1. 脏读 2. 不可重复读 3. 丢失更新

意向锁是将锁定的对象分为多个层次,对最细粒度的对象进行上锁,首先需要对粗粒度的对象上锁。

触发器

触发器只能创建在永久表上,不能对临时表创建触发器。触发器是行触发的。

视图

视图的主要用途是被用作一个抽象装置,只需要按照视图定义来取数据或更新数据。视图是一种虚拟存在的表。

联合索引

主键索引与唯一索引的区别

  1. 主键是一种约束,唯一索引是一种索引。两者在本质上是不同的。
  2. 主键创建后一定包含一个唯一索引,但是唯一索引不一定是主键。
  3. 主键不允许为空,而唯一索引可以为空。
  4. 一个表最多只能创建一个主键,但是可以创建多个唯一索引。

索引的优缺点

什么时候使用索引

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段应该作为索引
  3. 查询中统计或分组字段
  4. 排序字段

什么时候不能使用索引

  1. 频繁更新的字段不适合创建索引
  2. where条件里用不到的字段不适合创建索引
  3. 表记录太少
  4. 数据重复且分布平均的字段

数据库中join的类型与区别

  1. inner join
  2. cross join
  3. left join
  4. right join

分库分表

数据库的IO瓶颈和CPU瓶颈都会导致数据库活跃连接数增加,进而逼近数据库可承载连接数的最大值。 IO瓶颈:磁盘读IO瓶颈,热点数据太多,数据库缓存放不下,每次查询时产生大量的IO,降低查询数据。解决方案【分库和垂直分表】

CPU瓶颈:SQL问题,包含join,group by,order by,非索引字段查询等,增加CPU运算的操作。解决方案【SQL优化,建立适当的索引,在业务Service层进行业务计算】单表数据量太大,查询时扫描的行太多,SQL效率低,CPU率先出现瓶颈。解决方案【水平分表】

分库分表工具:

分库分表总结:

锁机制

另一种分类方式

行锁分为三级,粒度从小到大依次是