Mysql面试总结

399 阅读3分钟

数据库三大范式是什么?

  • 第一范式:列是原子得,即每个列都不可以再拆分。
  • 第二范式:在第一范式的基础上, 一是表必须有一个主,非主键列必须完全依赖于主键,而不能是依赖于主键的一部分。
  • 第三范式:在第二范式的基础上,非主键列只直接依赖于主键,不能存在传递依赖。

MyISAM索引与InnoDB索引的区别?

InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。

InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。

MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。

InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。

mysql有哪些数据类型?

整数类型,实数类型,字符串类型,枚举型,日期和时间类型

InnoDB引擎的4大特性

  • 插入缓冲(insert buffer): 只对于非聚集索引(非唯一)的插入和更新有效,对于每一次的插入不是写到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,如果在则直接插入;若不在,则先放到Insert Buffer 中,再按照一定的频率进行合并操作。

  • 二次写(double write)

  • 自适应哈希索引(ahi): Innodb存储引擎会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,二级索引成为热数据,建立哈希索引可以带来速度的提升。

    优点:可以加快索引速度

    缺点: hash自适应索引会占用innodb buffer pool; 自适应hash索引只适合搜索等值的查询

  • 预读(read ahead)

索引有哪几种类型?

  • 主键索引(聚集索引)
  • 普通索引(二级索引)
  • 哈希索引
  • 全文索引

索引的数据结构

  • B树
  • B+tree性质
  • 哈希索引

创建索引时需要注意什么?

  • 非空字段
  • 取值离散大的字段
  • 索引字段越小越好

百万级别或以上的数据如何删除?

先删除索引,在删数据,再重新构建索引

什么是最左前缀原则?什么是最左匹配原则?

  • 最左前缀原则: 指的是联合索引中,最左边的字段是索引字段,即有序的,后面的字段是无序的,
  • 最左前缀匹配原则 : mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。

B树和B+树的区别

在B树中,你可以将键和值存放在内部节点和叶子节点;但在B+树中,内部节点都是键,没有值,叶子节点同时存放键和值。

B+树的叶子节点有一条链相连,而B树的叶子节点各自独立。

使用B树的好处

非叶子节点也可以存放数据,可以把热点数据放在离根节点近的位置,可以提高查找效率。

使用B+树的好处

(1)由于B+树的非叶子节点只存放键,不存放值,因此,可以在非叶子节点中可以存放更多的键,有利于更快地缩小查找范围。 (2)叶子节点由一条链相连, 当需要进行一次全数据遍历的时候,B+树只需要使用O(logN)时间找到最小的一个节点,然后通过链进行O(N)的顺序遍历即可。而B树则需要对树的每一层进行遍历,这会需要更多的内存置换次数,因此也就需要花费更多的时间.

什么是聚簇索引?何时使用聚簇索引与非聚簇索引?

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

非聚簇索引: 将数据和索引分开存储,索引结构的叶子节点指向了数据的对应行, myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,

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

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

什么是数据库事务?

事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上的一组操作,要么都执行,要么都不执行。

事物的四大特性(ACID)介绍一下?

原子性,一致性,隔离性,持久性

按照锁的粒度分数据库锁有哪些?

行级锁:行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

表级锁: 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。特点:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

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

InnoDB存储引擎的锁的算法有哪三种?

  • Record lock:单个行记录上的锁
  • Gap lock:间隙锁,锁定一个范围,不包括记录本身
  • Next-key lock:record+gap 锁定一个范围,包含记录本身

数据库的乐观锁和悲观锁是什么?怎么实现的?

悲观锁:事务在每次读写的时候都悲观的认为会有别的时候同时修改同一数据,因此每次都会再对应的资源上加共享锁或排他锁

乐观锁:事务在每次读写时乐观的认为不会由其他事务修改同一数据,所以不会对读写的资源上锁,通过版本号version和CAS算法实现。

为什么要尽量设定一个主键?

主键是数据库确保数据行在整张表中唯一性的保障,即使业务上本张表没有主键,也建议添加一个自增长的ID列作为主键。设定了主键之后,在后续的删改查的时候可能更加快速以及确保操作数据范围安全。

分布式id

实现方案:UUID,redis,雪花算法

雪花算法: Snowflake生成的是Long类型的ID,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特。 Snowflake ID组成结构:正数位(占1比特)+ 时间戳(占41比特)+ 机器ID(占5比特)+ 数据中心(占5比特)+ 自增值(占12比特),总共64比特组成的一个Long类型。

redis: Redis也同样可以实现,原理就是利用redis的 incr命令实现ID的原子性自增。 假如没有及时持久化,重启redis后可能会出现重复id的可能性

UUID:生成字符串id,缺点: (1)无序的字符串,不具备趋势自增特性.(2) 没有具体的业务含义.

主从复制的作用?

  • 主数据库出现问题,从服务器可以顶上。
  • 可以进行数据库层面的读写分离。
  • 可以在从数据库上进行日常备份。

MySQL主从复制工作原理?

  • 从库会生成两个线程,一个I/O线程,一个SQL线程;
  • I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;
  • 主库会生成一个log dump线程,用来给从库I/O线程传binlog;
  • SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;

索引失效的情况

  • 在where子句中进行null值判断的话会导致引擎放弃索引而产生全表扫描
SELECT id FROM table WHERE num is null
  • 避免在where子句中使用!= ,< >这样的符号,否则会导致引擎放弃索引而产生全表扫描
SELECT id FROM table WHERE num != 0
  • 避免在where子句中使用or来连接条件,因为如果俩个字段中有一个没有索引的话,引擎会放弃索引而产生全表扫描
SELECT id FROM table WHERE num = 0 OR num = 1
  • 避免在where子句中=的左边使用表达式操作或者函数操作
SELECT id FROM table WHERE num / 2 = 1
SELECT id FROM table WHERE SUBSTRING(name,1,2) = 'wise'
  • 避免在where子句中使用like模糊查询
SELECT id FROM table WHERE name LIKE 'wise'

数据库优化

  • 尽量把字段设置为NOT NULL,这样在执行查询的时候,数据库不用去比较NULL值。
  • 对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。 ENUM类型被当成数组类型进行处理,数值类型的处理比文本类型快的多。
  • 使用连接(JOIN)来代替子查询(Sub-Queries)。
  • 使用联合(UNION)来代替手动创建的临时表。