MySQL基础知识点汇总

1. MySQL 存储引擎 MyISAM 与 InnoDB 的区别?
  • Innodb引擎:Innodb引擎提供了对数据库 ACID 事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。
  • MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键,表级锁定 。
2. binlog 是什么?

binlog 是 MySql Server 层维护的一种二进制日志,其主要是用来记录对 MySql 数据更新的 SQL 语句,并以”事务”的形式保存在磁盘中。

binlog 作用:

  • 主从复制
  • 恢复数据(通过 mysqlbinlog 等工具)

MySql binlog 日志有 row , statement , mixed 三种格式,可通过 my.cnf 配置文件。

  • statement 模式下,每一条会修改数据的sql都会记录在binlog中。不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。由于sql的执行是有上下文的,因此在保存的时候需要保存相关的信息,同时还有一些使用了函数之类的语句无法被记录复制。
  • row 级别下,不记录sql语句上下文相关信息,仅保存哪条记录被修改。记录单元为每一行的改动,基本是可以全部记下来但是由于很多操作,会导致大量行的改动(比如alter table),因此这种模式的文件保存的信息太多,日志量太大。
  • mixed,一种折中的方案,普通操作使用statement记录,当无法使用statement的时候使用row。
3. 索引有哪几种类型?
  • 主键索引: 数据列不允许重复,不允许为NULL,一个表只能有一个主键。
  • 唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。(可以通过 ALTER TABLE table_name ADD UNIQUE (column); 创建唯一索引)
  • 普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。(可以通过ALTER TABLE table_name ADD INDEX index_name (column);创建普通索引)
  • 全文索引: 是目前搜索引擎使用的一种关键技术。(InnoDB不支持)
4. 创建索引有哪些注意事项?
  1. “最左前缀匹配原则”,是组合索引非常重要的原则,mysql 会一直向右匹配直到遇到范围查询如 >、<、between、like 就停止匹配【注意不包含等于号=】,比如 a = 1 and b = 2 and c > 3 and d = 4 如果建立 (a,b,c,d) 顺序的索引,d 是用不到索引的?,如果建立(a,b,d,c) 的索引则都可以用到?,a,b,d的顺序可以任意调整。
  2. = 和 in 可以乱序,比如 a = 1 and b = 2 and c = 3 建立 (a,b,c) 索引可以任意顺序,mysql 的查询优化器会帮你优化成索引可以识别的形式。
  3. 较频繁作为查询条件的字段才去创建索引。为经常需要排序、分组和联合操作的字段建立索引,经常需要 ORDER BY、GROUP BY、DISTINCT 和 UNION 等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。
  4. 更新频繁字段不适合创建索引。
  5. 若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)。
  6. 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
  7. 定义有外键的数据列一定要建立索引。
  8. 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
  9. 对于定义为 text、image 和 bit 的数据类型的列不要建立索引。
  10. 如果通配符 % 不出现在开头,则可以用到索引,但根据具体情况不同可能只会用其中一个前缀。在 like “value%” 可以使用索引,但是 like “%value%” 不会使用索引,走的是全表扫描。
5. 什么是最左前缀原则?

最左前缀:顾名思义,就是最左优先,上例中我们创建了 lname_fname_age 多列索引,相当于创建了 (lname) 单列索引,(lname,fname) 组合索引以及 (lname,fname,age) 组合索引,在执行查询时,只能使用一个索引。

6. 什么是聚簇索引与非聚簇索引?

聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据。

非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam 通过 key_buffer 把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer 命中时,速度慢的原因。

澄清一个概念:

innodb中,在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值。

7. 非聚簇索引一定会回表查询吗?

不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。


举个简单的例子

假设我们在员工表的年龄上建立了索引,那么当进行 select age from employee where age < 20 的查询时,在索引的叶子节点上,已经包含了age 信息,不会再次进行回表查询。

8. 事物的四大特性(ACID)
  • 原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  • 一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
  • 隔离性: 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  • 持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
9. 什么是脏读?幻读?不可重复读?
  • 脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
  • 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。【再次读的时候数据变化了】
  • 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。【再次读的时候数据多了】
10. SQL 标准定义了四个隔离级别?
  • READ-UNCOMMITTED(读未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • READ-COMMITTED(读已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

这里需要注意的是:Mysql 默认采用的 REPEATABLE_READ 隔离级别,Oracle 默认采用的 READ_COMMITTED隔离级别。

事务隔离机制的实现基于锁机制和并发调度。其中并发调度使用的是MVVC(多版本并发控制),通过保存修改的旧版本信息来支持并发一致性读和回滚等特性。因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内容):,但是你要知道的是InnoDB 存储引擎默认使用 **REPEATABLE-READ(可重读)**并不会有任何性能损失。InnoDB 存储引擎在 分布式事务 的情况下一般会用到**SERIALIZABLE(可串行化)**隔离级别。

11. 隔离级别与锁的关系?
  • 在Read Uncommitted级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突
  • 在Read Committed级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;
  • 在Repeatable Read级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,也就是必须等待事务执行完毕以后才释放共享锁。
  • SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。
12. 行级锁与表级锁?

行级锁

行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。

特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

表级锁

表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。

特点:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

页级锁

页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。

特点:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

完。

码先生
Author: 码先生

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注