MySQL——MySQL常见的面试知识

1、事务四大特性

  • 原子性: 根据定义,原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做。即要么转账成功,要么转账失败,是不存在中间的状态!MySQLInnoDB引擎是靠 undo log (回滚日志)来实现的undo log能够保证在事务回滚时,能够撤销所有已经执行成功的SQL
  • 一致性: 根据定义,一致性是指事务执行前后,数据处于一种合法的状态,这种状态是语义上的而不是语法上的。通过原子性、隔离性、持久性是为了保证一致性所做的措施。
  • 隔离性: 根据定义,隔离性是指多个事务并发执行的时候,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。通过MVCC机制和锁解决。
  • 持久性: 根据定义,持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。MySQL事务的持久性是通过redo log来实现的。

binlog 的作用:(1)是用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。(2)用于数据库的基于时间点的还原。

1.1、redo logbin log的区别

  • redo log是在InnoDB存储引擎层产生,而bin logMySQL数据库的上层产生的,并且二进制日志不仅仅针对INNODB存储引擎,MySQL数据库中的任何存储引擎对于数据库的更改都会产生二进制日志。

  • 两种日志记录的内容形式不同。MySQLbinlog是逻辑日志,其记录是对应的SQL语句。而INNODB存储引擎层面的重做日志是物理日志。

  • 两种日志与记录写入磁盘的时间点不同,二进制日志只在事务提交完成后进行一次写入。而INNODB存储引擎的重做日志在事务进行中不断地被写入,并日志不是随事务提交的顺序进行写入的。

    二进制日志仅在事务提交时记录,并且对于每一个事务,仅在事务提交时记录,并且对于每一个事务,仅包含对应事务的一个日志。而对于INNODB存储引擎的重做日志,由于其记录是物理操作日志,因此每个事务对应多个日志条目,并且事务的重做日志写入是并发的,并非在事务提交时写入,其在文件中记录的顺序并非是事务开始的顺序。

  • bin log不是循环使用,在写满或者重启之后,会生成新的bin log文件,redo log是循环使用。

  • bin log可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

1.2、三大范式

  • 第一范式: 数据库中所有的属性字段都是不可分解的,即我们创建的属性在此字段中一定是你设计表的最小的字段值,遵循数据的原子性;
  • 第二范式: 表中的属性字段必须依赖于表的主键;
  • 第三范式: 不能出现传递依赖。

第一范式规定表中的每个列都应该是不可分割的最小单元。第二范式是在满足第一范式的基础上,规定表中的非主键列不存在对主键的部分依赖。第三范式是在满足第一范式和第二范式的基础上,规定表中的列不存在对非主键列的传递依赖。使用数据库三范式的优势是:表的结构更简单、优雅,表的逻辑和条理性更强,并且使用三范式可以很大程度的减少表中的冗余数据,很好的节省了数据库的存储资源。

2、事务的并发?事务隔离级别,每个级别会引发什么问题,MySQL默认是哪个级别?

  • ISOLATION_DEFAULT :用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
  • ISOLATION_READ_UNCOMMITTED 未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
  • ISOLATION_READ_COMMITTED 提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL Server 的默认级别
  • ISOLATION_REPEATABLE_READ 可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别
  • ISOLATION_SERIALIZABLE :串行化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
隔离级别 脏读 不可重复读 幻读
读未提交(Read Uncommitted
读已提交(Read committed ×
可重复读(Repeatable read × ×
可串行化(Serializable × × ×

如何设置隔离级别,即隔离级别的命令?

// 设置read uncommitted级别:
set session transaction isolation level read uncommitted;

// 设置read committed级别:
set session transaction isolation level read committed;

// 设置repeatable read级别:
set session transaction isolation level repeatable read;

// 设置serializable级别:
set session transaction isolation level serializable;

3、什么是脏读、幻读和不可重复度?

答: 不可重复读的和幻读很容易混淆,不可重复读侧重于修改幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

  • 脏读: 事务 A 读取事务 B 更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。
  • 不可重复读: 事务A 多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。
  • 幻读: 事务A,读取所有工资为1000的员工,共读取10条记录,事务Bemployee表插入了一条员工记录,工资也为1000,事务A再次读取所有工资为1000的员工,共读取到了11条记录,这就产生了幻读。

4、MySQL常见的三种存储引擎的区别?

  • InnoDB 支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)
  • MyISAM:插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用。
  • MEMORY:所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。

5、MySQLMyISAMInnoDB两种存储引擎在,事务、锁级别,各自的适用场景?

5.1、MyISAM 特点

  • 不支持行锁(MyISAM只有表锁),读取时对需要读到的所有表加锁,写入时则对表加排他锁;
  • 不支持事务
  • 不支持外键
  • 不支持崩溃后的安全恢复
  • 在表有读取查询的同时,支持往表中插入新纪录
  • 支持BLOBTEXT的前500个字符索引,支持全文索引
  • 支持延迟更新索引,极大地提升了写入性能
  • 对于不会进行修改的表,支持压缩表,极大地减少了磁盘空间的占用

5.2、InnoDB 特点

  • 支持行锁,采用MVCC来支持高并发,有可能死锁
  • 支持事务
  • 支持外键
  • 支持崩溃后的安全恢复
  • 不支持全文索引

5.3、InnoDB四大特性

  • 插入缓冲(insert buffer)
  • 二次写(double write)
  • 自适应哈希索引(ahi)
  • 预读(read ahead)

5.4、MyISAM InnoDB 两者的应用场景

  • MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的 SELECT 查询,那么MyISAM是更好的选择。
  • InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的 INSERT UPDATE 操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

6、查询语句不同元素(wherejoinlimitgroup byhaving等等)执行先后顺序?

  1. 执行where xx对全表数据做筛选,返回第1个结果集。
  2. 针对第1个结果集使用group by分组,返回第2个结果集。
  3. 针对第2个结果集中的每1组数据执行select xx,有几组就执行几次,返回第3个结果集。
  4. 针对第3个结集执行having xx进行筛选,返回第4个结果集。
  5. 针对第4个结果集排序。

通过一个顺口溜总结下顺序:我(W)哥(G)是(SH)偶(O)像。按照执行顺序的关键词首字母分别是W(where)->G(Group)->S(Select)->H(Having)->O(Order),对应汉语首字母可以编成容易记忆的顺口溜:我(W)哥(G)是(SH)偶(O)像

7、什么是临时表,临时表什么时候删除?

答: MySQL用于存储一些中间结果集的表,临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。为什么会产生临时表:一般是由于复杂的SQL导致临时表被大量创建。临时表分为两种,一种是内存临时表,一种是磁盘临时表

  • 内存临时表采用的是 memory 存储引擎
  • 磁盘临时表采用的是myisam存储引擎(磁盘临时表也可以使用InnoDB存储引擎,通internal_tmp_disk_storage_engine参数来控制使用哪种存储引擎,从 mysql5.7.6 之后默认为 InnoDB 存储引擎,之前版本默认为myisam存储引擎)。分别通过Created_tmp_disk_tablesCreated_tmp_tables 两个参数来查看产生了多少磁盘临时表和所有产生的临时表(内存和磁盘)。

内存临时表空间的大小由两个参数控制:tmp_table_size max_heap_table_size 。一般来说是通过两个参数中较小的数来控制内存临时表空间的最大值,而对于开始在内存中创建的临时表,后来由于数据太大转移到磁盘上的临时表,只由max_heap_table_size参数控制。针对直接在磁盘上产生的临时表,没有大小控制。

哪些操作会使用到临时表?

  • UNION查询;
  • 用到TEMPTABLE算法或者是UNION查询中的视图;
  • ORDER BYGROUP BY的子句不一样时或者单独ORDER BY
  • 表连接中,ORDER BY的列不是驱动表中的;(指定了联接条件时,满足查询条件的记录行数少的表为[驱动表],未指定联接条件时,行数少的表为[驱动表],多表联合查询时
  • DISTINCT 查询并且加上ORDER BY时或者单独DISTINCT时候;
  • SQL中用到SQL_SMALL_RESULT选项时;
  • FROM中的子查询;
  • 子查询或者SEMI-JOIN时创建的表。

8、非关系型数据库和关系型数据库区别,优势比较?

8.1、关系型数据库和非关系型数据库的区别

  • 关系型数据库: OracleDB2Microsoft SQL ServerMicrosoft AccessMySQL等。
  • 非关系型数据库: NoSqlCloudant。临时性键值存储(memcachedRedis)、永久性键值存储(ROMARedis)、面向文档的数据库(MongoDBCouchDB)、面向列的数据库(CassandraHBase

8.2、非关系型数据库的优势

  • 格式灵活: 存储数据的格式可以是key,value形式、文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
  • 速度快: nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
  • 高扩展性: 基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
  • 成本低: nosql数据库部署简单,基本都是开源软件。
  • 易于数据的分散,分布式数据库

8.3、非关系型数据库的缺点

答: 不提供关系型数据库对事务的处理NoSQL数据库只应用在特定领域,基本上不进行复杂的处理,但它恰恰弥补了之前所列举的关系型数据库的不足之处。

8.4、关系型数据库的优势

  • 易于维护: 都是使用表结构,格式一致;
  • 使用方便: SQL 语言通用,可用于复杂查询
  • 复杂操作: 支持SQL,可以进行Join等复杂查询,可用于一个表以及多个表之间非常复杂的查询;
  • 事务支持:使得对于安全性能很高的数据访问要求得以实现;
  • 由于以标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处)。

8.5、关系型数据库的缺点

  • 读写性能比较差,尤其是海量数据的高效率读写;
  • 固定的表结构,灵活度欠缺
  • 高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。

9、什么是存储过程?

答: 存储过程是将一个预编译的 SQL 语句存储在数据库中,再次调用不需要编译。优点是:允许模块化的设计,就是说只需要创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。

10、存储过程的优点(不推荐)

  • 效率高: 存储过程编译一次后,就会存到数据库,每次调用时都直接执行。而普通的SQL语句我们要保存到其他地方(例如:记事本上),都要先分析编译才会执行。所以想对而言存储过程效率更高;
  • 降低网络流量: 存储过程编译好会放在数据库,我们在远程调用时,不会传输大量的字符串类型的SQL语句;
  • 复用性高: 存储过程往往是针对一个特定的功能编写的,当再需要完成这个特定的功能时,可以再次调用该存储过程;
  • 可维护性高: 当功能要求发生小的变化时,修改之前的存储过程比较容易,花费精力少;
  • 安全性高: 完成某个特定功能的存储过程一般只有特定的用户可以使用,具有使用身份限制,更安全。

11、存储过程和函数的区别?

  • 返回值的区别:函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有
  • 调用的区别:函数可以在查询语句中直接调用,而存储过程必须单独调用

11、SQL 关键字的执行顺序?

MySQL——MySQL常见的面试知识_第1张图片

12、MySQL的页有多大

答: 可以看出 InnoDB默认的一页大小为 16384B = 16384/1024 = 16kb

在计算机中磁盘存储数据最小单元是扇区,一个扇区的大小是512字节,而文件系统(例如 XFS/EXT4)他的最小单元是块,一个块的大小是 4k,而对于我们的InnoDB存储引擎也有自己的最小储存单元——页(Page),一个页的大小是 16K

show global status like 'innodb_page_size';

12、数据库是如何实现分页的,假设有100万条数据如何优化分页查询?

12.1、方法1:直接使用数据库提供的 SQL 语句

  • 语句样式MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N
  • 适应场景: 适用于数据量较少的情况(元组百/千级)
  • 原因/缺点:全表扫描,速度会很慢有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3).。Limit限制的是从结果集的M位置处取出N条输出,其余抛弃.

12.2、方法2:建立主键或唯一索引, 利用索引(假设每页10条)

  • 语句样式:MySQL中,可用如下方法:SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) LIMIT M
  • 适应场景:适用于数据量多的情况(元组数上万);
  • 原因:索引扫描,速度会很快。有朋友提出:因为数据查询出来并不是按照id_pk排序的,所以会有漏掉数据的情况,只能方法3。

12.3、方法3:基于索引再排序

  • 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M
  • 适应场景: 适用于数据量多的情况(元组数上万). 最好ORDER BY后的列对象是主键或唯一所以,使得 ORDER BY 操作能利用索引被消除但结果集是稳定的(稳定的含义,参见方法1);
  • 原因: 索引扫描,速度会很快。 但MySQL的排序操作,只有ASC没有DESC(DESC是假的,未来会做真正的DESC,期待…)。

12.4、方法4:基于索引使用 prepare

答: 第一个问号表示,第二个表示每页元组数。

  • 语句样式: MySQL中,可用如下方法:PREPARE stmt_name FROM SELECT * FROM 表名称 WHERE id_pk > (pageNum * 10) ORDER BY id_pk ASC LIMIT M
  • 适应场景: 大数据量;
  • 原因: 索引扫描,速度会很快。prepare语句又比一般的查询语句快一点。

12.5、方法5:利用 MySQL 支持 ORDER 操作可以利用索引快速定位部分元组,避免全表扫描

答: 比如: 读第1000到1019行元组(pk是主键/唯一键)。

SELECT * FROM your_table WHERE pk>=1000 ORDER BY pk ASC LIMIT 0,20

12.6、方法6: 利用"子查询/连接+索引"快速定位元组的位置,然后再读取元组

比如(id是主键/唯一键,蓝色字体时变量)。

利用子查询示例:

SELECT * FROM your_table WHERE id <= (SELECT id FROM your_table ORDER BY id desc 
LIMIT (page-1)*pagesize ORDER BY id desc LIMIT $pagesize

利用连接示例:

SELECT * FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY id desc
LIMIT (page-1)*pagesize AS t2 WHERE t1.id <= t2.id ORDER BY t1.id desc LIMIT $pagesize

`

你可能感兴趣的:(MySQL,mysql,数据库,1024程序员节)