Mysql

设计一个关系型数据库(RDBMS)

1:程序实列

- 物理数据的存储管理。(尽可能的减少IO,一次性的读取所需要的所有数据)
- 缓存机制。
- SLQ解析。(慢sql日志;explain;)索引;锁模块。 
- 日志管理(MongoDB)
- 权限划分(DBA来做的事情)
- 容灾机制

2:存储(文件系统)

1.1 索引

  • 为什么使用索引?
    • 让我们避免全表扫描去查找数据,从而提高检索效率。
  • 什么样的信息能成为索引?
    • 主键;唯一键;只要是能让数据具备一定区分性的字段。
      -** 索引的数据结构?**
    • Mysql 最主要是B±Tree结构进行查找
  • 密集索引和悉数索引的区别?
    • 密集索引文件中的每个搜索码都对应一个索引值;一个表中能创建一个密集索引。
    • 稀疏素银文件中只为某些值建立索引值。
      在这里插入图片描述
      在这里插入图片描述
  • 如何定位并优化慢查询sql?
    • 根据慢日志定位慢查询日志。通过命令:show variables like ‘%quer%’;查询quer相关的配置变量(long_query_time;slow-query_long_file;slow_query_log;)
    • 使用Explain;show profile 等工具分析sql。
      • 属性type:system-const-eq_ref-ref-fulltext-ref_or_null-index_merge-unique_subquery-index_subquery-range-index-all;其中index;all都是全表扫描,需要优化sql;
      • 属性extra,出现下面的两个也就表示咱们有可能需要优化了。:
        • Using filesort:表示Musql会对结果使用一个外部索引排序,而不是从表里按索引次序读到相关内容。可能在内存或者磁盘上进行排序。Mysql中无法利用索引完成的排序操作称为“文件排序”。
        • Using temporary:表示Mysql在对查询结果排序时使用临时表。常见于排序Order by 和 分组查询Group by;
    • 修改sql或者尽量让sql走索引。
  • 联合索引的最左匹配原则的成因?
    • Mysql 创建符合索引排序的原则:首先会对复合索引的第一个索引字段进行排序,再对第二个字段进行排序。其实类似与Order By。
  • 索引是建立得越多越好吗?不是,有以下三点。
    • 数据量小的表不需要建立索引,建立索引会增加额外的索引开销。
    • 数据表更需要维护索引,因此更多的索引意味着更多的维护成本。
    • 更多的索引意味着也需要更多的空间。

1.2 锁

  • MyISAM与InnoDB关于锁方面的区别是什么

    • MyISAM默认用的是表级锁,不支持行级锁。
    • InnoDB默认用的是行级锁,也支持表级锁。
    • InnoDB 当查询的时候不走索引的时候,用的是表级锁;反之则用的是行级锁。
    • 共享锁和排他锁的兼容性
      • 加了写锁时,无论你再加读锁还是写锁都需要等待写锁的释放才能执行。
      • 加了读锁时,再加写锁则需要等待读锁的释放;而在家读锁是不影响的。
  • 行级锁一定要比表级锁要好?

    • 未必,锁的粒度越细,代价越高。相比表级锁之间在表的头不加锁来讲,表级锁还要扫描到某行的时候,对其上锁,代价甚大。InnoDB支持事务的同时,也相比MyISAM带来了更大的开销。InnoDB必须有且仅有一个聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要查询两次,先查到主键,然后再通过主键查询到数据。而MyISAM是非聚集索引,数据;文件是分离的,索引保存的是数据文件的指针,主键索引和辅助索引是独立的,因此MyISAM在纯检索系统中, 也就是增删改查很少的系统中,其性能要好于InnoDB。
  • MyISAM 适合的场景

    • 适合频繁执行全表count语句,用一个变量保存了一个表的行数。
    • 对数据进行增删查改的频率不高,查询非常频繁。因为增删会涉及到锁表操作。虽然可以通过一些配置让插入数据从表的尾部插入数据,但还是会产生很多的碎片。
    • 没有事务的场景。
  • InnoDB 适合的场景

    • 不保存数据的具体的行数,执行select count(1) 是需要重新扫描统计。
    • 适合增删改查都相当频繁的系统,只是某些行被锁。
    • 可靠行要求比较高,要求支持事务。
  • 数据库锁的分类

    • 按锁的粒度划分:表级锁;行级锁;页级锁。
    • 按锁级别划分:功效所;排它锁。
    • 按枷锁的方式划分:自动锁和显示锁。
      • 自动锁:InnoDB的删改查,是InnoDB自动给我们加上的。
      • 显示锁:for update; lock in share more mode。
    • 按操作划分,可分为DML锁;DDL锁;对DB操作的锁(增删查改)就是DML锁,对表结构进行变更的就算DDL锁,如Alter table。
    • 按使用方式划分可分为:乐观锁和悲观锁。 悲观锁其实就算DB的表锁,加锁会造成系统的负担且影响系统的并行性。乐观锁为一般数据不会造成冲突,所以在数据提交更新的时候,才会正式对数据的冲突与否进行检测。相对于悲观所,乐观锁并不会使用数据库提供的锁机制。
  • 数据库事务(ACID)的四大特性

    • 原子性(atomicity):整个事务中的所有操作要么全部提交成功,要么全部失败回滚。
    • 一致性(consistency):数据库总是从一个一致性的状态转换到另外一个一致性的状态。比如说整个数据库重点所有操作都是一次性全部提交,所以事务中所做的修改不会保存到数据库中去。
    • 隔离性(isolation)【通常来说】,一个事务所作的所有修改操作在提交以前,对其它事物都是不可见的。
      • 未提交读(read-uncommitted-脏读):事务中的修改,即使事务没有提交,对其它的事务也都是可见的。换句 话说,也就是事务可读取未提交的数据。注意,这个级别会导致很多问题,慎用!
      • 提交读(read-committed-不可重复读):大部分数据库系统的默认隔离级别(mysql不是)。简而言之,一个事务开始时,只能“看见”已经提交的事务所作的修改。存在两次查询,可能查询出不一样的结果。比如说:事务T1读取一行记录后,事务T2修改了此条记录,则事务T1再次读取得到的是事务T2修改后的结果。
      • 可重复读(repeatable-read-幻读):(InnoDBl默认级别)该级别解决了脏读的问题。保证了在同一个事务中多次读取同样的记录的结果是一致的。但是理论上,此隔离级别还是无法解决另外一个幻读的问题。所谓幻读,就是当事务T1读取某个范围内的数据后,事务T2在此范围内新增了一条数据,则事务T1再次读取此范围的数据时,会产生幻行。
      • 可串行化(serializable):是最高的隔离级别。通过强制事务串行执行,避免了幻读问题。简单来说,可串行化会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑该级别。
        持久性:一旦事务提交,则其所作的所有修改操作都将永久保存到数据库中。
    • 持久性(durability)
  • 当前读和快照读

    • 当前读:不管你上的是共享锁还是排他锁都是当前读。因为它读取的是记录的最新版本,并且读取之后还得保证其它事务不能影响到当前的事务。示例:select…lock in share mode;for update;update;delete;insert;
    • 快照读:不加锁的非阻塞读,可能读到的数据可能是历史版本并不是最新的数据。
  • InnoDB可重复读隔离级别下如何避免幻读

    • 表象:快照读(非阻塞读)–伪MVCC
    • 内在:next-key锁(行锁+grp锁)
  • next-key锁(行锁+Gap锁)

    • 行锁
    • gap锁(间隙锁):锁定一个范围,但不包括记录本身。目的是为了防止同一事物的两次当前读,避免幻读的情况。在RC及其隔离级别更低的事务中是不存在的,这也是RC及更低事务无法避免幻读的原因。
  • InnoDB加Gap锁的场景

    • 如果where条件全部命中(精确查询),则不会用Gap锁,只会加记录锁。
    • 如果where 条件部分命中或者全不命中,则会加Gap锁。
    • 非唯一索引的当前读
    • 不走索引的当前读,相比表锁,间隙锁的代价更高。
  • RC;RR级别下的InnoDB的非阻塞读如何实现

    • 数据行里的DB_TRX_ID(事务ID);DB_ROLL_RTR(回滚指针);DB_ROW_ID(行号)字段;
    • undo 日志(存储的是老版数据,主要用于事务回滚;快照读)。
    • read view;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值