八股DAY1--MySQL面试题总结
MySQL面试题总结
1.什么是MySQL
关系型数据库 开源
创建表:CREATE TABLE
删除表:DROP TABLE
设定主键:PRIMARY KEY
升序/降序:ORDER BY
- 升:ASC
- 降:DESC
MySQL性能差的原因:
- SQL查询使用了全表扫描
- 查询语句过于复杂
- 多表 JOIN 或 嵌套子查询
- 单表数据量过大
添加索引能解决性能问题 一些热点数据还可以通过增加Redis缓存
2.两张表怎么连接
内连接 inner join
两个表中都有的数据才会被返回
找出两个表的交集
外连接 outer join
两个表的并集
左连接 left join 保留左表中符合条件的记录 右表中有匹配的记录,则返回 没有则填nulll
场景:一个表中有 另一个表中可能没有
右连接 right join 保留右表中的记录 ...(左连接的镜像)
交叉连接 cross join 返回两张表的笛卡尔积,左表中的每一行和右表中的每一行进行组合
3.数据库三大范式
第一范式:确保表中的每一列都是不可分割的基本数据单元
第二范式:要求表中的每一列都和主键直接相关
第三范式:非主键列应该依赖于主键列
建表的时候需要考虑哪些问题:
- 是否符合三范式 确保主键不可分 消除非主键依赖 确保字段仅依赖于主键
- 选择合适的数据类型
- 字符集选择utf8mb4
- 数据过大时考虑分表
4.varchar和char的区别
varchar是可变长度字符类型 容纳65533个字符
char是固定字符长度字符类型 定义一个char字符不管如何占用10个字符空间
5.blob和text有什么区别
blob用于存储二进制数据,如:图片和音频的url
txt存储文本数据,如:文章 评论 日志
6.DATETIME和TIMESTAMP有什么区别?
- DATETIME直接存储日期和时间的完整值 与时区无关 默认值null 占用8字节
- TIMESTAMP存储的是Unix时间戳,1970-01-01 00:00:01 UTC 以来的秒数,受时区影响 默认时间当前时间 占用4字节
7.in和exists的区别
- IN,mysql首先会执行子查询 再执行外部查询 子查询内存查询结果都要存储到内存中 适用与子查询结果集较小的情况
- EXISTS 会对外部查询的每一行执行一次子查询 关注子查询是否返回行 而不是返回的具体值 适用于子查询集很大的情况
NULL值陷:
IN: 如果子查询的结果集中包含 NULL 值,可能会导致意外的结果。例如,WHERE column IN (subquery),如果 subquery 返回 NULL,则 column IN (subquery) 永远不会为真,除非 column 本身也为 NULL。
EXISTS: 对 NULL 值的处理更加直接。EXISTS 只是检查子查询是否返回行,不关心行的具体值,因此不受 NULL 值的影响。
8 记录货币用什么类型比较好?
- 电商\交易\账单等涉及货币的场景 使用 DECIMAL 精确数值类型 不会出现浮点数误差
- 银行涉及到交付的场景 可以使用 BIGINT 将货币×固定数 避免浮点问题
9.怎么存储 emoji
- emoji (表情) 是4个字节的字符 mysql的utf8只支持3个字节
- 存储emoji要使用 utf8mb4 字符集
10.DROP DELETE 和 TRUNCATE的区别
- DROP 是物理删除 删除整张表 包括表结构 不能回滚
- DELETE 支持行级删除 可带WHERE条件 可以回滚
- TRUNCATE 用于清空表中的所有数据 会保留表结构 不能回滚
11.UNION 和 UNION ALL 的区别
- UNION 自动去除合并后的重复行
- UNION ALL 不会去重
12.COUNT(1) COUNT(*) COUNT(列名) 区别
- LnnoDB引擎中 count(1) 和 count(*) 没有区别 都是用来统计所有的行 包括NULL
- count(*) 直接用索引统计 而不是全表扫描
- count(1) 会被mysql优化为 count(1)
- count(列名) 只统计名不为NULL的行数
13.SQL查询的执行顺序
- 执行FROM确定主表
- 执行JOIN连接
- 进行WHERE过滤 ----先执行是为了减少数据量
- 进行GROUP BY 分组
- HAVING 过滤聚合结果 ----只能过滤聚合数据
- SELECT 选择最终列
- ORDER BY 排序
- LIMIT限制返回 ----减少数据传输
14.SQL常用命令
数据库操作命令
- CREATE DATABASE database_name; 用于创建数据库;
- DROP DATABASE database_name;用于删除数据库;
- SHOW DATABASES;用于显示所有数据库;
- USE database_name; 用于切换数据库。
表操作命令
CREATE TABLE table_name (列名1 数据类型1, 列名2 数据类型2,...);用于创建表;DROP TABLE table_name;用于删除表;SHOW TABLES;用于显示所有表;DESCRIBE table_name;用于查看表结构;ALTER TABLE table_name ADD column_name datatype;用于修改表。
数据的 CRUD 命令
INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);用于插入数据;SELECT column_names FROM table_name WHERE condition;用于查询数据;UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;用于更新数据;DELETE FROM table_name WHERE condition;用于删除数据。
索引和约束的创建修改命令
CREATE INDEX index_name ON table_name (column_name);用于创建索引;ALTER TABLE table_name ADD PRIMARY KEY (column_name);用于添加主键;ALTER TABLE table_name ADD CONSTRAINT fk_name FOREIGN KEY (column_name) REFERENCES parent_table (parent_column_name);用于添加外键。
用户和权限管理的命令
CREATE USER 'username'@'host' IDENTIFIED BY 'password';用于创建用户;GRANT ALL PRIVILEGES ON database_name.table_name TO 'username'@'host';用于授予权限;REVOKE ALL PRIVILEGES ON database_name.table_name FROM 'username'@'host';用于撤销权限;DROP USER 'username'@'host';用于删除用户。
事务控制的命令
START TRANSACTION;用于开始事务;COMMIT;用于提交事务;ROLLBACK;用于回滚事务。
15.MySQL 函数
处理字符函数:
- CONAT() 用于连接两个或多个字符
- LENGTH() 用于返回字符串长度
- SUBSTRING() 从字符串中提取子字符串
- REPLACE() 替换字符串中的某部分
- TRIM() 去除字符串两侧的空格或其他指定字符
处理数字的函数
- ABS() 返回一个数的绝对值
- ROUND() 四舍五入
- MOD() 取余
日期和时间处理函数
- NOW() 返回当前时间和日期
- CURDATE() 返回当前日期
汇总函数
- SUM() 总和
- AVG() 平均值
- COUNT() 某列的行数
逻辑函数
- IF() 条件为真 返回一个值
- CASE 根据一系列条件返回值
16.SQL的隐式数据类型转换
- 当一个整数和一个浮点数相加时,整数会被转换为浮点数。
- 当一个字符串和一个整数相加时,字符串会被转换为整数。
17.SQL的语法树解析
- SQL 语法树解析是将 SQL 查询语句转换成抽象语法树 —— AST 的过程
- 是数据库引擎处理查询的第一步,也是防止 SQL 注入的重要手段。
- 通常分为 3 个阶段。
- 第一个阶段,词法分析:拆解 SQL 语句,识别关键字、表名、列名等。
- 第二个阶段,语法分析:检查 SQL 是否符合语法规则,并构建抽象语法树。
- 第三个阶段,语义分析:检查表、列是否存在,进行权限验证等。
18.MySQL基础架构
MySQL 采用分层架构,主要包括连接层、服务层、和存储引擎层。
- 连接层主要负责客户端连接的管理,包括验证用户身份、权限校验、连接管理等。可以通过数据库连接池来提升连接的处理效率。
- 服务层是 MySQL 的核心,主要负责查询解析、优化、执行等操作。在这一层,SQL 语句会经过解析、优化器优化,然后转发到存储引擎执行,并返回结果。这一层包含查询解析器、优化器、执行计划生成器、日志模块等。
- 存储引擎层负责数据的实际存储和提取。MySQL 支持多种存储引擎,如 InnoDB、MyISAM、Memory 等。
19.SQL语句执行流程
- 客户端发送 SQL 查询语句到 MySQL 服务器。
- MySQL 服务器的连接器开始处理这个请求,跟客户端建立连接、获取权限、管理连接。
- 解析器对 SQL 语句进行解析,检查语句是否符合 SQL 语法规则,确保数据库、表和列都是存在的,并处理 SQL 语句中的名称解析和权限验证。
- 优化器负责确定 SQL 语句的执行计划,这包括选择使用哪些索引,以及决定表之间的连接顺序等。
- 执行器会调用存储引擎的 API 来进行数据的读写。
- 存储引擎负责查询数据,并将执行结果返回给客户端。客户端接收到查询结果,完成这次查询请求。
20.更新语句执行顺序
一条 UPDATE 语句的执行过程包括读取数据页、加锁解锁、事务提交、日志记录等多个步骤。
21.MySQL的段区页行
-
段:表空间由多个段组成,常见的段有数据段、索引段、回滚段等。
创建索引时会创建两个段,数据段和索引段,数据段用来存储叶子节点中的数据;索引段用来存储非叶子节点的数据。
回滚段包含了事务执行过程中用于数据回滚的旧数据。
-
区:段由一个或多个区组成,区是一组连续的页,通常包含 64 个连续的页,也就是 1M 的数据。
使用区而非单独的页进行数据分配可以优化磁盘操作,减少磁盘寻道时间,特别是在大量数据进行读写时。
-
页:页是 InnoDB 存储数据的基本单元,标准大小为 16 KB,索引树上的一个节点就是一个页。
也就意味着数据库每次读写都是以 16 KB 为单位的,一次最少从磁盘中读取 16KB 的数据到内存,一次最少写入 16KB 的数据到磁盘。
-
行:InnoDB 采用行存储方式,意味着数据按照行进行组织和管理,行数据可能有多个格式,比如说 COMPACT、REDUNDANT、DYNAMIC 等。
22.MySQL存储引擎
MyISAM、InnoDB、MEMORY

浙公网安备 33010602011771号