MySQL数据库面试大全

目录

一、mysq|的日志怎么查询

1、查看日志状态命令

2、开启日志命令

3、数据库表记录操作日志

4、修改为表格的命令

5、通过命令查看命令

6、使用数据库表记录操作日志会增加数据的压力,因此建议使用文件记录操作日志:

二、查询速度慢的原因, 如何解决:

三、数据库的事务是什么?怎么使用

四、主键、外键、索引的各自的含义以及区别

1、主键

2、外键

3、索引

4、三者的区别

五、ACID是指事务的四个关键特性,其英文全称为Atomicity、Consistency、Isolation和Durability,分别对应事务的原子性、一致性、隔离性和持久性。

六、索引的数据结构是什么

1.哈希表(散列表)

2.有序数组

3.二叉树(N叉树)

七、什么是前缀索引

八、怎么创建前缀索引?

九、数据库有几种表之间的连接形式(左连接,右连接,内连接,完全连接)

1、内联接

2、外联接。

十、三大范式

十一、Hash 和 B+ 树索引的区别?

十二、为何使用 B+ 树而非二叉查找树做索引?

十三、MySQL 中有哪些常见日志?

十四、常见的聚合查询?

十五、Where 和 Having 的区别?

十六、In 和 Exists 的区别?

十七、Union 和 Union All 的区别?


一、mysq|的日志怎么查询

1、查看日志状态命令

show VARIABLES like 'gen%'

2、开启日志命令

set GLOBAL general_log=ON

3、数据库表记录操作日志

此命令是检测日志输出的方式,这里检测到是以文件的形式,这里可以改为表格的形式

show VARIABLES like 'log_output'

4、修改为表格的命令

set GLOBAL log_output='TABLE'

5、通过命令查看命令

SELECT * FROM mysql.general_log

6、使用数据库表记录操作日志会增加数据的压力,因此建议使用文件记录操作日志:

set GLOBAL log_output='FILE';

TRUNCATE TABLE mysql.log_output

二、查询速度慢的原因, 如何解决:

MySQL查询速度慢的原因有很多,常见的几种原因包括:

  1. 缺乏索引或索引未被充分利用:没有正确地创建索引或者查询语句中没有使用到索引,导致数据库需要进行全表扫描来查找所需数据,从而降低查询速度。
  2. I/O吞吐量小:磁盘读写速度慢、网络带宽不足等问题都会导致I/O吞吐量小,形成了瓶颈效应,进而影响查询速度。
  3. 缺少计算列导致查询不优化:计算列是一种预先计算并存储在数据库中的列,可以提高查询性能。如果没有适当地创建计算列,查询语句可能需要对大量数据进行计算,导致查询速度变慢。
  4. 内存不足:当数据库所需的内存超出了可用内存的限制时,数据库可能会将一部分数据存储在磁盘上,从而导致查询速度下降。

解决MySQL查询速度慢的方法包括:

  1. 创建合适的索引:分析查询语句和数据表结构,确定合适的索引策略,创建适当的索引,以加快查询速度。
  2. 优化查询语句:通过优化查询语句的编写方式,避免不必要的计算和重复操作,从而提高查询效率。
  3. 增加硬件资源:增加服务器的内存、磁盘和网络带宽等硬件资源,以提高整体系统的性能。
  4. 使用缓存机制:利用缓存机制,将频繁查询的结果缓存起来,减少对数据库的访问次数,提高查询速度。
  5. 数据库分区:将大表分成多个分区,可以提高查询效率,减少查询范围。

总结来说,解决MySQL查询速度慢的问题需要综合考虑索引优化、查询语句优化、硬件资源增加、缓存机制和数据库分区等方面的方法。根据具体情况选择合适的解决方案,可以提高MySQL的查询性能。

 

三、数据库的事务是什么?怎么使用

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

四、主键、外键、索引的各自的含义以及区别

1、主键

在MySQL中,主键(Primary Key)是指一张表中用来唯一标识每条记录的字段或者字段集合。一个表只能有一个主键,且主键必须满足以下三个条件:

唯一性:每个主键的取值必须唯一,即不允许出现两条记录的主键取值相同的情况。

非空性:主键列不能包含NULL值,否则将无法区分记录。

稳定性:主键列的值在任何时候都不能被修改,这是为了保证表中记录始终能够被唯一标识。

在MySQL中,通常可以通过在定义表的时候设置主键实现。可以把一个列定义为主键并用“PRIMARY KEY”关键字声明它,也可以在多个列上定义复合主键。。如果一个表没有主键,那么在某些查询中可能会影响性能,并且可能会导致数据不一致。因此,在设计数据库时建议为每个表定义一个主键

2、外键

  1. 在MySQL数据库中,外键(Foreign Key)是指一个表中的字段,在另一个表中作为主键使用。换言之,外键是通过一个或多个列来定义两个表之间关系的约束。它描述了两个表之间的关系,确保引用表中的数据符合相应的完整性要求。
  2. 在MySQL中,定义外键约束可以使用“FOREIGN KEY”语句,必须满足以下两个条件:
    1. 外键列值必须与其引用表中的主键或唯一键值匹配,保证数据的正确性和可靠性。
    2. 在更新和删除操作时,必须遵循特定的行为,比如:当引用表的某一行被删除时,相关的行应该被删除或将其外键列置为NULL值等。
  3. 有了外键约束后,可以保证两个表之间的数据始终保持同步,同时也防止了数据的矛盾和冲突,增加了数据的安全性和可维护性。但是,由于外键的检索需要占用更多的系统资源,所以在设计数据库结构时不应该过度使用外键

3、索引

MySQL索引是一种数据结构,用于加速MySQL数据库中的查询操作。它允许快速查找特定值或一组值对应的行。索引可以在一个表上定义一个或多个列(字段),每个索引都有一个或多个列(字段)的值按照特定的方式排序,并保存在数据结构中以提升查询效率。

MySQL索引通常具有以下几个特点:

  1. 索引可以加速查询:通过使用索引,我们可以在数据集合中快速定位到满足特定条件的记录,从而加速查询的速度。
  2. 索引会占用空间:索引需要占用磁盘空间来存储索引信息,因此在设计索引时需要权衡空间和性能之间的平衡。
  3. 索引可以降低写入性能:由于索引需要在更新、插入和删除操作时维护,所以过多的索引可能会拖慢写入操作的性能。
  4. 索引可以提高表的安全性:通过创建唯一索引或主键索引等约束,可以增强表的数据完整性和安全性。

在MySQL中,可根据不同的需求创建不同类型的索引。最常见的索引包括主键索引、唯一索引、普通索引、全文索引等。利用索引可以提高查询的速度,但是需要合理地设计与使用索引,否则可能会影响查询性能并占用过多的存储空间。

4、三者的区别

主键、外键和索引是MySQL数据库中常见的概念,它们的区别如下:

  1. 主键(Primary Key):主键用于唯一标识一张表中每条记录,通常由一个或多个列组成。主键要求每条记录都必须具有唯一标识,且不允许为空。主键可以作为其他表中的外键参考。通过主键可以方便地定位、更新以及删除表中的某条记录。
  2. 外键(Foreign Key):外键是指一个表中的字段,在另一个表中作为主键使用。外键约束保证了数据在表之间的完整性,并使得表之间具有联系。外键定义了两个表之间的关系,要求在外键所指向的表中存在对应的行。在 MySQL 中,外键是用于约束数据完整性的重要工具。
  3. 索引(Index):索引用于加速 SQL 查询语句的执行速度。索引在数据库的某个列上进行构建,它可以帮助 MySQL 更快地定位和提取查询语句所需要的数据。索引可分为普通索引和唯一索引两种,除此之外还有全文搜索索引等其他类型的索引。
  4. 总体来说,主键是用于表示一张表中每条记录的唯一标识,外键是用于表示关联两张表之间的字段,而索引用于提高 SQL 查询语句的执行速度。三者之间具有不同的作用和用途,但都可以提高数据库操作的效率与安全性。

五、ACID是指事务的四个关键特性,其英文全称为Atomicity、Consistency、Isolation和Durability,分别对应事务的原子性、一致性、隔离性和持久性。

  1. 原子性(Atomicity):事务是一个不可分割的操作单位,要么全部执行成功,要么全部执行失败。即使在系统发生故障时,也必须保证事务的原子性。
  2. 一致性(Consistency):事务执行前后,数据的完整性约束没有被破坏,如数据的唯一性、实体完整性、参照完整性等。
  3. 隔离性(Isolation):多个事务并发执行时,每个事务都应该彼此独立,互不干扰。每个事务看到的数据视图应该与其他事务的数据视图相互隔离,这样可以避免数据不一致的问题。
  4. 持久性(Durability):事务一旦提交,对数据的修改就是永久性的,即使系统崩溃,修改的数据也能够恢复。
  5. 这四大特性是保证数据库管理系统(DBMS)中事务处理正确和可靠的基础。如果一个事务满足ACID特性,那么就可以保证数据的一致性和可靠性,从而使数据库系统更加稳定和安全。

六、索引的数据结构是什么

索引可能有三种数据结构哈希表、有序数组和N叉树。MySQL使用了B+树。

1.哈希表(散列表)

哈希表是一种以键 - 值(key-value)存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。

因为是使用hash算法对key求值取余得到其在数组的存储位置。

所以,哈希表这种结构适用于只有等值查询的场景,比如 Memcached 及其他一些 NoSQL 引擎。在范围查询中需要全表扫描,是很慢的。

2.有序数组

有序数组在范围查询中优势非常明显,可以采用二分法,能大大缩短查询时间,尤其是数据量比较大时。时间复杂度是时间复杂度是 O(log(N))。如果往中间插入一条数据,就需要把后续数组都往后移,这个时候有序数组的成本就很高了.

所以,有序数组索引只适用于静态存储引擎,

3.二叉树(N叉树)

根据叶子节点的内容,索引类型分为主键索引和非主键索引。

主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。

非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。

基于主键索引和普通索引的查询有什么区别?

主键索引的叶子节点存的是整行数据。如果查询条件是主键就能获取整行数据。非主键索引的value是主键Id,如果查询条件是非主键,那么先查非主键索引得到主键id,根据主键Id再查主键索引得到整行数据。

从性能和存储空间方面考量,自增主键往往是比业务字段更合理的选择。可以参考:优化 | InnoDB表一定要用自增列做主键

七、什么是前缀索引

所谓前缀索引,说白了就是对文本的前几个字符建立索引(具体是几个字符在建立索引时去指定),比如以产品名称的前 10 位来建索引,这样建立起来的索引更小,查询效率更快!

有点类似于 Oracle 中对字段使用 Left 函数来建立函数索引,只不过 MySQL 的这个前缀索引在查询时是内部自动完成匹配的,并不需要使用 Left 函数。

八、怎么创建前缀索引?

建立前缀索引的方式,方法很简单,通过如下方式即可创建!

ALTER TABLE table_name ADD KEY(column_name(prefix_length));

其中prefix_length这个参数,就是前缀长度的意思,通常通过如下方式进行确认,步骤如下:

第一步,先计算某字段全列的区分度。

SELECT COUNT(DISTINCT column_name) / COUNT(*) FROM table_name;

第二步,然后再计算前缀长度为多少时和全列的区分度最相似

SELECT COUNT(DISTINCT LEFT(column_name, prefix_length)) / COUNT(*) FROM table_name;

最后,不断地调整prefix_length的值,直到和全列计算出区分度相近,最相近的那个值,就是我们想要的值。

下面以某个测试表为例,数据体量在 100 万以上,表结构如下!

CREATE TABLE `tb_test` (

  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,

  `name` varchar(100) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4

九、数据库有几种表之间的连接形式(左连接,右连接,内连接,完全连接)

1、内联接

(select a.*,b.* from a inner join b on a.id=b.aId)

内连接又包括等值连接,非等值连接,默认的是等值链接。

内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。

2、外联接。

左连接(select a.*,b.* from a left join b on a.id=b.aId)

右链接(select a.*,b.* from a right join b on a.id=b.aId)

外联接可以是左向外联接、右向外联接或完整外部联接。在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:

1)LEFT JOIN或LEFT OUTER JOIN

2)RIGHT JOIN 或 RIGHT OUTER JOIN

3)FULL JOIN 或 FULL OUTER JOIN

3、 完全连接( select a.*,b.* from a full join b on a.id=b.aId)

交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积.

十、三大范式

  1. 第一范式(1NF):属性不可分割,即每个属性都是不可分割的原子项。(实体的属性即表中的列)

判断表是否符合第一范式,列是否可以再分,得看需求,如果将电话号和地址分开才能满足查询等需求时,那之前的表设计就是不满足1NF的,如果电话号和地址拼接作为一个字段也可以满足查询、存储等需求时,那它就满足1NF。

  1. 第二范式(2NF):满足第一范式;且不存在部分依赖,即非主属性必须完全依赖于主属性。(主属性即主键;完全依赖是针对于联合主键的情况,非主键列不能只依赖于主键的一部分)

在满足1NF的前提下,表中不存在部分依赖,非主键列要完全依赖于主键。(主要是说在联合主键的情况下,非主键列不能只依赖于主键的一部分)

  1. 第三范式(3NF):满足第二范式;且不存在传递依赖,即非主属性不能与非主属性之间有依赖关系,非主属性必须直接依赖于主属性,不能间接依赖主属性。(A -> B, B ->C, A -> C)
    1. 非主键列越少的表。(1NF强调列不可再分;2NF和3NF强调非主属性列和主属性列之间的关系)
    2. 如代码表(sexcode),非主键列只有一个sex_desc;
    3. 或者将学生表的主键设计为primary key(id,name,sex_code,phone),这样非主键列只有address,更容易符合3NF。

十一、Hash 和 B+ 树索引的区别?

Hash

  1. Hash 进行等值查询更快,但无法进行范围查询。因为经过 Hash 函数建立索引之后,索引的顺序与原顺序无法保持一致,故不能支持范围查询。同理,也不支持使用索引进行排序。
  2. Hash 不支持模糊查询以及多列索引的最左前缀匹配,因为 Hash 函数的值不可预测,如 AA 和 AB 的算出的值没有相关性。
  3. Hash 任何时候都避免不了回表查询数据.
  1. 虽然在等值上查询效率高,但性能不稳定,因为当某个键值存在大量重复时,产生 Hash 碰撞,此时查询效率反而可能降低。

B+ Tree

  1. B+ 树本质是一棵查找树,自然支持范围查询和排序。
  1. 在符合某些条件(聚簇索引、覆盖索引等)时候可以只通过索引完成查询,不需要回表。
  2. 查询效率比较稳定,因为每次查询都是从根节点到叶子节点,且为树的高度。
  3. 为何使用 B+ 树而非二叉查找树做索引?

我们知道二叉树的查找效率为 O(logn),当树过高时,查找效率会下降。另外由于我们的索引文件并不小,所以是存储在磁盘上的。

文件系统需要从磁盘读取数据时,一般以页为单位进行读取,假设一个页内的数据过少,那么操作系统就需要读取更多的页,涉及磁盘随机 I/O 访问的次数就更多。将数据从磁盘读入内存涉及随机 I/O 的访问,是数据库里面成本最高的操作之一。

因而这种树高会随数据量增多急剧增加,每次更新数据又需要通过左旋和右旋维护平衡的二叉树,不太适合用于存储在磁盘上的索引文件。

十二、为何使用 B+ 树而非二叉查找树做索引?

  1. 我们知道二叉树的查找效率为 O(logn),当树过高时,查找效率会下降。另外由于我们的索引文件并不小,所以是存储在磁盘上的。
  2. 文件系统需要从磁盘读取数据时,一般以页为单位进行读取,假设一个页内的数据过少,那么操作系统就需要读取更多的页,涉及磁盘随机 I/O 访问的次数就更多。将数据从磁盘读入内存涉及随机 I/O 的访问,是数据库里面成本最高的操作之一。
  3. 因而这种树高会随数据量增多急剧增加,每次更新数据又需要通过左旋和右旋维护平衡的二叉树,不太适合用于存储在磁盘上的索引文件。

十三、MySQL 中有哪些常见日志?

重做日志(redo log):物理日志

作用是确保事务的持久性。 redo 日志记录事务执行后的状态,用来恢复未写入 data file 的已提交事务数据。

回滚日志(undo log):逻辑日志

作用是保证数据的原子性。 保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。

二进制日志(binlog):逻辑日志

常用于主从同步或数据同步中,也可用于数据库基于时间点的还原。

错误日志(errorlog)

记录着 MySQL 启动和停止,以及服务器在运行过程中发生的错误的相关信息。在默认情况下,系统记录错误日志的功能是关闭的,错误信息被输出到标准错误输出。

普通查询日志(general query log)

记录了服务器接收到的每一个命令,无论命令语句是否正确,因此会带来不小开销,所以也是默认关闭的。

慢查询日志(slow query log)

记录执行时间过长和没有使用索引的查询语句(默认 10s),同时只会记录执行成功的语句。

中继日志(relay log)

在从节点中存储接收到的 binlog 日志内容,用于主从同步。

十四、常见的聚合查询?

使用聚合函数的查询就是聚合查询。所有的聚合函数(UDAF)都应该支持分组查询,内置的聚合函数有:

  1. sum(列名) 求和      
  2. max(列名) 最大值     
  3. min(列名) 最小值     
  4. avg(列名) 平均值     
  5. first(列名)   第一条记录  
  6. last(列名)    最后一条记录 
  7. count(列名)   统计记录数   注意和count(*)的区别

十五、Where 和 Having 的区别?

where 子句的作用是在对查询结果进行分组前,将不符合条件的行去掉,即在分组之前过滤数据,where条件中不能包含聚组函数,使用where条件过滤出特定的行。

having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件过滤出特定的组,也可以使用多个分组标准进行分组。

总结一下条件的过滤顺序:on->join->where->group by->having。

十六、In 和 Exists 的区别?

in 适合内表比外表数据小的情况,exists 适合内表比外表数据大的情况。如果查询的内外表大小相当,则二者效率差别不大。

十七、Union 和 Union All 的区别?

  • Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序
  • Union All:对两个结果集进行并集操作,包括重复行,不进行排序

Union 因为要进行重复值扫描,所以效率低。如果合并没有刻意要删除重复行,那么就使用Union All。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Daniel Hao(找工作中)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值