当前位置: 首页 > news >正文

MySQL 面经

1、什么是 MySQL?

MySQL 是一个开源的关系型数据库,现在隶属于 Oracle 公司。是我们国内使用频率最高的一种数据库,我本地安装的是比较新的 8.0 版本。

1.1 怎么删除/创建一张表?

可以使用 DROP TABLE 来删除表,使用 CREATE TABLE 来创建表。创建表的时候,可以通过 PRIMARY KEY 设定主键。

CREATE TABLE users (id INT AUTO_INCREMENT,name VARCHAR(100) NOT NULL,email VARCHAR(100),PRIMARY KEY (id)
);

1.2 请写一个升序/降序的 SQL 语句?

在 SQL 中,可以使用 ORDER BY 子句来对查询结果进行升序或者降序。默认情况下,查询结果是升序的,如果需要降序,可以通过 DESC 关键字来实现。如果需对多个字段进行排序,例如按工资降序,按名字升序,就可以 ORDER BY salary DESC, name ASC 来完成:

SELECT id, name, salary
FROM employees
ORDER BY salary DESC, name ASC;

1.3 MySQL出现性能差的原因有哪些?

可能是 SQL 查询使用了全表扫描,也可能是查询语句过于复杂,如多表 JOIN 或嵌套子查询。也有可能是单表数据量过大。通常情况下,添加索引就能解决大部分性能问题。对于一些热点数据,还可以通过增加 Redis 缓存,来减轻数据库的访问压力。

2、两张表怎么进行连接?

可以通过内连接 inner join、外连接 outer join、交叉连接 cross join 来合并多个表的查询结果。

2.1 什么是内连接?

内连接用于返回两个表中有匹配关系的行。假设有两张表:用户表和订单表,想查询有订单的用户就可以使用内连接 users INNER JOIN orders,按照用户 ID 关联就行了。

SELECT users.name, orders.order_id
FROM users
INNER JOIN orders ON users.id = orders.user_id;

只有那些在两个表中都存在 user_id 的记录才会出现在查询结果中。

2.2 什么是外连接?

和内连接不同,外连接不仅返回两个表中匹配的行,还返回没有匹配的行,用 null 来填充。外连接又分为左外连接 left join 和右外连接 right join。left join 会保留左表中符合条件的所有记录,如果右表中有匹配的记录,就返回匹配记录,否则就用 null 填充,常用于某表中有,但另外一张表中可能没有的数据的查询场景。假设要查询所有用户以及他们的订单,即使用户没有下单,就可以使用左连接:

SELECT users.id, users.name, orders.order_id
FROM users
LEFT JOIN orders ON users.id = orders.user_id;

右连接就是左连接的镜像,right join 会保留右表中符合条件的所有记录。

2.3 什么是交叉连接?

交叉连接会返回两张表的笛卡尔积,将左表的每一行与右表的每一行进行组合,返回的行数是两张表行数的乘积。

SELECT A.id, B.id
FROM A
CROSS JOIN B;

3、内连接、左连接、右连接有什么区别?

MySQL 的连接主要分为内连接和外连接,外连接又可以分为左连接和右连接。
在这里插入图片描述
内连接可以用来找出两个表中共同的记录,相当于两个数据集的交集。左连接和右连接可以用来找出两个表中不同的记录,相当于两个数据集的并集。两者的区别是,左连接会保留左表中符合条件的所有记录,右连接则刚好相反。

4、说一下数据库的三大范式?

在这里插入图片描述

  1. 第一范式:表的每一列都是不可分割的基本数据单元:在这里插入图片描述
  2. 第二范式:在满足1NF的基础上,非主键字段必须完全依赖于整个主键。
    在这里插入图片描述
  3. 第三范式:在满足2NF的基础上,非主键字段不能间接依赖其他非主键字段(消除传递依赖)。
    在这里插入图片描述

4.1 建表的时候需要考虑哪些问题?

首先需要考虑表是否符合数据库的三大范式,确保字段不可再分,消除非主键依赖,确保字段仅依赖于主键等。然后在选择字段类型时,应该尽量选择合适的数据类型。在字符集上,尽量选择 utf8mb4,不仅可以支持中文和英文,还可以支持表情符号等。当数据量较大时,比如上千万行数据,需要考虑分表。比如订单表,可以采用水平分表的方式来分散单表存储压力。

5、varchar 与 char 的区别?

  1. varchar 是可变长度的字符类型,理论上最多可以容纳 65535 个字符,但考虑到字符集,以及 MySQL 需要 1 到 2 个字节来表示字符串长度,所以实际上最大可以容纳到 65533。
  2. char 是固定长度的字符类型,当定义一个 CHAR(10) 字段时,不管实际存储的字符长度是多少,都只会占用 10 个字符的空间。如果插入的数据小于 10 个字符,剩余的部分会用空格填充。(GBK 中文占 2 字节,UTF-8 占 3 字节)

6、blob 和 text 有什么区别?

blob 用于存储二进制数据,比如图片、音频、视频、文件等;但实际开发中,我们都会把这些文件存储到 OSS 或者文件服务器上,然后在数据库中存储文件的 URL。text 用于存储文本数据,比如文章、评论、日志等。

7、DATETIME 和 TIMESTAMP 有什么区别?

  1. DATETIME 直接存储日期和时间的完整值,与时区无关。
  2. TIMESTAMP 存储的是 Unix 时间戳,1970-01-01 00:00:01 UTC 以来的秒数,受时区影响。
    另外,DATETIME 的默认值为 null,占用 8 个字节;TIMESTAMP 的默认值为当前时间 CURRENT_TIMESTAMP,占 4 个字节,实际开发中更常用,因为可以自动更新。

8、in 和 exists 的区别?

使用 IN 时,MySQL 会首先执行子查询,然后将子查询的结果集用于外部查询的条件。这意味着子查询的结果集需要全部加载到内存中。而 EXISTS 会对外部查询的每一行,执行一次子查询。如果子查询返回任何行,则 EXISTS 条件为真。EXISTS 关注的是子查询是否返回行,而不是返回的具体值。

-- IN 的临时表可能成为性能瓶颈
SELECT * FROM users 
WHERE id IN (SELECT user_id FROM orders WHERE amount > 100);
-- EXISTS 可以利用关联索引
SELECT * FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.amount > 100);

IN 适用于子查询结果集较小的情况。如果子查询返回大量数据,IN 的性能可能会下降,因为它需要将整个结果集加载到内存。而 EXISTS 适用于子查询结果集可能很大的情况。由于 EXISTS 只需要判断子查询是否返回行,不需要加载整个结果集,因此在某些情况下性能更好,特别是当子查询可以使用索引时。

8.1 NULL 值陷阱了解吗?

  1. IN: 如果子查询的结果集中包含 NULL 值,可能会导致意外的结果。例如,WHERE column IN (subquery),如果 subquery 返回 NULL,则 column IN (subquery) 永远不会为真,除非 column 本身也为 NULL。
  2. EXISTS: 对 NULL 值的处理更加直接。EXISTS 只是检查子查询是否返回行,不关心行的具体值,因此不受 NULL 值的影响。

9、记录货币用什么字段类型比较好?

货币在数据库中 MySQL 常用 Decimal 和 Numeric 类型表示,这两种类型被 MySQL 实现为同样的类型。他们被用于保存与货币有关的数据。例如 salary DECIMAL(9,2),9 (precision) 代表将被用于存储值的总的小数位数,而 2 (scale) 代表将被用于存储小数点后的位数。存储在 salary 列中的值的范围是从-9999999.99 到 9999999.99。DECIMAL 和 NUMERIC 值作为字符串存储,而不是作为二进制浮点数,以便保存那些值的小数精度。之所以不使用 float 或者 double 是为了避免二进制误差。

10、怎么存储 emoji?

MySQL 的 utf8 字符集仅支持最多 3 个字节的 UTF-8 字符,但是 emoji 表情(😊)是 4 个字节的 UTF-8 字符,所以在 MySQL 中存储 emoji 表情时,需要使用 utf8mb4 字符集。MySQL 8.0 已经默认支持 utf8mb4 字符集。

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

11、drop、delete 与 truncate 的区别?

  1. drop:属于 DDL,不可回滚,从数据库中删除表,所有数据行,索引和权限也会被删除,删除速度最快。
  2. delete:属于 DML,可回滚,表结构还在,删除表的全部或者一部分数据行,删除速度慢,需要逐行删除 。
  3. truncate:属于 DDL,不可回滚,表结构还在,删除表中的所有数据,删除速度快。
    因此,在不再需要一张表的时候,用 drop;在想删除部分数据行时候,用 delete;在保留表而删除所有数据的时候用 truncate。

12、UNION 与 UNION ALL 的区别?

  1. 如果使用 UNION,合并后会去除重复的记录行。
  2. 如果使用 UNION ALL,合并后不会去除重复的记录行。
  3. 从效率上说,UNION ALL 要比 UNION 快很多,如果合并没有刻意要删除重复行,那么就使用 UNION All。

13、count(*)、count(1) 与 count(列名) 的区别?

  1. count(*):统计表中所有行的数量,无论列值是否为 NULL。
  2. count(1):与 count(*) 功能完全相同,1 是一个常量值,不依赖任何列。
  3. count(列名):仅统计指定列中非 NULL 值​​的行数。若某行的该列为 NULL,则不计入统计。

14、SQL 查询语句的执行顺序了解吗?

在这里插入图片描述

  1. FROM:对 FROM 子句中的左表 <left_table> 和右表 <right_table> 执行笛卡儿积,产生虚拟表 VT1。
  2. ON:对虚拟表 VT1 应用 ON 筛选,只有那些符合 <join_condition> 的行才被插入虚拟表 VT2 中。
  3. JOIN:如果指定了 OUTER JOIN,那么保留表中未匹配的行作为外部行添加到虚拟表 VT2 中,产生虚拟表 VT3。
  4. WHERE:对虚拟表 VT3 应用 WHERE 过滤条件,只有符合 <where_condition> 的记录才被插入虚拟表 VT4 中。
  5. GROUP BY:根据 GROUP BY 子句中的列,对 VT4 中的记录进行分组操作,产生 VT5。
  6. CUBE|ROLLUP:对表 VT5 进行 CUBE 或 ROLLUP 操作,产生表 VT6。
  7. HAVING:对虚拟表 VT6 应用 HAVING 过滤器,只有符合 <having_condition> 的记录才被插入虚拟表 VT7 中。
  8. SELECT:第二次执行 SELECT 操作,选择指定的列,插入到虚拟表 VT8 中。
  9. DISTINCT:去除重复数据,产生虚拟表 VT9。
  10. ORDER BY:将虚拟表 VT9 中的记录按照 <order_by_list> 进行排序操作,产生虚拟表 VT10。
  11. LIMIT:取出指定行的记录,产生虚拟表 VT11,并返回给查询用户。

15、介绍一下 MySQL 的常用命令?

在这里插入图片描述

15.1 说说数据库操作命令?

  1. 创建数据库:
CREATE DATABASE database_name;
  1. 删除数据库:
DROP DATABASE database_name;
  1. 选择数据库:
USE database_name;

15.2 说说表操作命令?

  1. 创建表:
CREATE TABLE table_name (column1 datatype,column2 datatype,...
);
  1. 删除表:
DROP TABLE table_name;
  1. 显示所有表:
SHOW TABLES;
  1. 查看表结构:
DESCRIBE table_name;
  1. 修改表
ALTER TABLE table_name ADD column_name datatype;

15.3 CRUD 命令?

  1. 插入数据:
INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);
  1. 查询数据:
SELECT column_names FROM table_name WHERE condition;
  1. 更新数据:
UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;
  1. 删除数据:
DELETE FROM table_name WHERE condition;

15.4 说说索引和约束的创建修改命令?

  1. 创建索引:
CREATE INDEX index_name ON table_name (column_name);
  1. 添加主键约束:
ALTER TABLE table_name ADD PRIMARY KEY (column_name);
  1. 添加外键约束:
ALTER TABLE table_name ADD CONSTRAINT fk_name FOREIGN KEY (column_name) REFERENCES parent_table (parent_column_name);

15.5 说说用户和权限管理的命令?

  1. 创建用户:
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
  1. 授予权限:
GRANT ALL PRIVILEGES ON database_name.table_name TO 'username'@'host';
  1. 撤销权限:
REVOKE ALL PRIVILEGES ON database_name.table_name FROM 'username'@'host';
  1. 删除用户:
DROP USER 'username'@'host';

15.6 说说事务控制的命令?

  1. 开始事务:
START TRANSACTION;
  1. 提交事务:
COMMIT;
  1. 回滚事务:
ROLLBACK;

16、MySQL bin 目录下的可执行文件了解吗?

  1. mysql:客户端程序,用于连接 MySQL 服务器。
  2. mysqladmin:MySQL 管理工具,可以用来执行一些管理操作。
  3. mysqlcheck:MySQL 命令行工具,用于检查、修复、分析和优化数据库表。
  4. mysqldump:MySQL 数据库备份工具,用于创建一个或多个 MySQL 数据库的 SQL 转储文件。
  5. mysqlimport:用于从文本文件中导入数据到数据库表中,非常适合用于批量导入数据。
  6. mysqlshow:用于显示 MySQL 数据库服务器中的数据库、表、列等信息。
  7. mysqlbinlog:用于查看 MySQL 二进制日志文件的内容,可以用于恢复数据、查看数据变更等。

17、MySQL 第 3-10 条记录怎么查?

可以使用 limit 语句,结合偏移量 offset 和行数 row_count 来实现:

SELECT * FROM table_name LIMIT 2, 8;
  • 2:偏移量,表示跳过前两条记录,从第 3 条记录开始。
  • 8:行数,表示从偏移量开始,返回 8 条记录。
    偏移量是从 0 开始的,即第一条记录的偏移量是 0;如果想从第 3 条记录开始,偏移量就应该是 2。

18、用过哪些 MySQL 函数?

MySQL 支持很多内置函数,包括字符串函数、数值函数、日期和时间函数、汇总函数、逻辑函数、格式化函数、类型转换函数等。

18.1 用过哪些字符串函数来处理文本?

  1. LENGTH():返回字符串的长度。
  2. CONCAT():连接两个或多个字符串。
  3. REPLACE():替换字符串中的某部分。
  4. SUBSTRING():从字符串中提取子字符串。
  5. LOWER() 和 UPPER():分别将字符串转换为小写或大写。
  6. TRIM():去除字符串两侧的空格或其他指定字符。
-- 获取字符串长度
SELECT LENGTH('沉默 王二') AS string_length;
-- 连接字符串
SELECT CONCAT('沉默', ' ', '王二') AS concatenated_string;
-- 替换字符串内容
SELECT REPLACE('沉默 王二', '王二', 'MySQL') AS replaced_string;
-- 提取子字符串
SELECT SUBSTRING('沉默 王二', 1, 5) AS substring;
-- 字符串转小写
SELECT LOWER('HELLO WORLD') AS lower_case;
-- 字符串转大写
SELECT UPPER('hello world') AS upper_case;
-- 去除字符串两侧的空格
SELECT TRIM('  沉默 王二  ') AS trimmed_string;

18.2 用过哪些数值函数?

  1. ABS():返回一个数的绝对值。
  2. CEILING():返回大于或等于给定数值的最小整数。
  3. FLOOR():返回小于或等于给定数值的最大整数。
  4. ROUND():四舍五入到指定的小数位数。
  5. MOD():返回除法操作的余数。
-- 返回绝对值
SELECT ABS(-123) AS absolute_value;
-- 向上取整
SELECT CEILING(123.45) AS ceiling_value;
-- 向下取整
SELECT FLOOR(123.45) AS floor_value;
-- 四舍五入
SELECT ROUND(123.4567, 2) AS rounded_value;
-- 余数
SELECT MOD(10, 3) AS modulus;

18.3 用过哪些日期和时间函数?

  1. NOW():返回当前的日期和时间。
  2. CURDATE():返回当前的日期。
  3. CURTIME():返回当前的时间。
  4. DATE_ADD() 和 DATE_SUB():在日期上加上或减去指定的时间间隔。
  5. DATEDIFF():返回两个日期之间的天数。
  6. YEAR(),MONTH(),DAY():分别返回日期的年、月、日部分。
-- 返回当前日期和时间
SELECT NOW() AS current_date_time;
-- 返回当前日期
SELECT CURDATE() AS current_date;
-- 返回当前时间
SELECT CURTIME() AS current_time;
-- 在日期上添加天数
SELECT DATE_ADD(CURDATE(), INTERVAL 10 DAY) AS date_in_future;
-- 计算两个日期之间的天数
SELECT DATEDIFF('2024-12-31', '2024-01-01') AS days_difference;
-- 返回日期的年份
SELECT YEAR(CURDATE()) AS current_year;

18.4 用过哪些汇总函数?

  1. SUM():计算数值列的总和。
  2. AVG():计算数值列的平均值。
  3. COUNT():计算某列的行数。
  4. MAX() 和 MIN():分别返回列中的最大值和最小值。
  5. GROUP_CONCAT():将多个行值连接为一个字符串。
-- 创建一个表并插入数据进行聚合查询
CREATE TABLE sales (product_id INT,sales_amount DECIMAL(10, 2)
);INSERT INTO sales (product_id, sales_amount) VALUES (1, 100.00);
INSERT INTO sales (product_id, sales_amount) VALUES (1, 150.00);
INSERT INTO sales (product_id, sales_amount) VALUES (2, 200.00);-- 计算总和
SELECT SUM(sales_amount) AS total_sales FROM sales;
-- 计算平均值
SELECT AVG(sales_amount) AS average_sales FROM sales;
-- 计算总行数
SELECT COUNT(*) AS total_entries FROM sales;
-- 最大值和最小值
SELECT MAX(sales_amount) AS max_sale, MIN(sales_amount) AS min_sale FROM sales;

18.5 用过哪些逻辑函数?

  1. IF():如果条件为真,则返回一个值;否则返回另一个值。
  2. CASE:根据一系列条件返回值。
  3. COALESCE():返回参数列表中的第一个非 NULL 值。
-- IF函数
SELECT IF(1 > 0, 'True', 'False') AS simple_if;
-- CASE表达式
SELECT CASE WHEN 1 > 0 THEN 'True' ELSE 'False' END AS case_expression;
-- COALESCE函数
SELECT COALESCE(NULL, NULL, 'First Non-Null Value', 'Second Non-Null Value') AS first_non_null;

18.6 用过哪些格式化函数?

  1. FORMAT():格式化数字为格式化的字符串,通常用于货币显示。
-- 格式化数字
SELECT FORMAT(1234567.8945, 2) AS formatted_number;

18.6 用过哪些类型转换函数?

  1. CAST():将一个值转换为指定的数据类型。
  2. CONVERT():类似于CAST(),用于类型转换。
-- CAST函数
SELECT CAST('2024-01-01' AS DATE) AS casted_date;
-- CONVERT函数
SELECT CONVERT('123', SIGNED INTEGER) AS converted_number;

19、说说 SQL 的隐式数据类型转换?

在 SQL 中,当不同数据类型的值进行运算或比较时,会发生隐式数据类型转换。比如:当一个整数和一个浮点数相加时,整数会被转换为浮点数,然后再相加。当一个字符串和一个整数相加时,字符串会被转换为整数,然后再相加。数据类型隐式转换会导致意想不到的结果,所以要尽量避免隐式转换。

SELECT 1 + 1.0; -- 结果为 2.0
SELECT '1' + 1; -- 结果为 2

可以通过显式转换来规避这种情况:

SELECT CAST('1' AS SIGNED INTEGER) + 1; -- 结果为 2

20、说说 SQL 的语法树解析?

抽象语法树(AST)是 SQL 解析过程的中间表示,使用树形结构表示 SQL 语句的层次和逻辑。语法树由节点组成,每个节点表示 SQL 语句中的一个语法元素。

  1. 根节点:通常是 SQL 语句的主要操作,例如 SELECT、INSERT、UPDATE、DELETE 等。
  2. 内部节点:表示语句中的操作符、子查询、连接操作等。例如,WHERE 子句、JOIN 操作等。
  3. 叶子节点:表示具体的标识符、常量、列名、表名等。例如,users 表、id 列、常量 1 等。
    以一个简单的 SQL 查询语句为例:
SELECT name, age FROM users WHERE age > 18;

这个查询语句的语法树可以表示为:

          SELECT/      \Columns     FROM/      \      |name      age  users|WHERE|age > 18

21、说说 MySQL 的基础架构?

MySQL 的架构大致可以分为三层,从上到下依次是:连接层、服务层、和存储引擎层。
在这里插入图片描述

  1. 连接层主要负责客户端连接的管理,包括验证用户身份、权限校验、连接管理等。通过数据库连接池来提升连接的处理效率。
  2. 服务层是 MySQL 的核心,主要负责查询解析、优化、执行等操作。在服务层 SQL 语句会经过解析、优化器优化,然后转发到存储引擎执行,并返回结果。服务层包含查询解析器、优化器、执行计划生成器、缓存(如查询缓存)、日志模块等。
  3. 存储引擎层负责数据的实际存储和提取,是 MySQL 架构中与数据交互最直接的层。MySQL 支持多种存储引擎,如 InnoDB、MyISAM、Memory 等。

21.1 binlog 写入在哪一层?

binlog 在服务层,负责记录 SQL 语句的变化。它记录了所有对数据库进行更改的操作,用于数据恢复、主从复制等。

22、一条查询语句如何执行?

在这里插入图片描述

  1. 客户端发送 SQL 查询语句到 MySQL 服务器。
  2. MySQL 服务器的连接器开始处理这个请求,跟客户端建立连接、获取权限、管理连接。
  3. 解析器对 SQL 语句进行解析,检查语句是否符合 SQL 语法规则,确保引用的数据库、表和列都是存在的,并处理 SQL 语句中的名称解析和权限验证。
  4. 优化器负责确定 SQL 语句的执行计划,这包括选择使用哪些索引,以及决定表之间的连接顺序等。
  5. 执行器会调用存储引擎的 API 来进行数据的读写。
  6. MySQL 的存储引擎是插件式的,不同的存储引擎在细节上面有很大不同。例如,InnoDB 是支持事务的,而 MyISAM 是不支持的。之后,会将执行结果返回给客户端。
  7. 客户端接收到查询结果,完成这次查询请求。

23、一条更新语句怎么执行的?

更新语句的执行是服务层和引擎层配合完成,数据除了要写入表中,还要记录相应的日志。
在这里插入图片描述

  1. 执行器先找引擎获取 ID = 2 这一行。ID 是主键,存储引擎检索数据,找到这一行。如果 ID = 2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
  2. 执行器拿到引擎给的行数据把这个值加上 1,比如原来是 N,现在就是 N + 1,得到新的一行数据,再调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中,并将这个更新操作记录到 redo log,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

24、说说 MySQL 的数据存储形式?

MySQL 是以表的形式存储数据的,而表空间的结构则由段、区、页、行组成。
在这里插入图片描述

  1. 段(Segment):表空间由多个段组成,常见的段有数据段、索引段、回滚段等。创建索引时会创建两个段,数据段和索引段,数据段用来存储叶子节点中的数据;索引段用来存储非叶子节点的数据。回滚段包含了事务执行过程中用于数据回滚的旧数据。
  2. 区(Extent):段由一个或多个区组成,区是一组连续的页,通常包含 64 个连续的页,也就是 1M 的数据。使用区而非单独的页进行数据分配可以优化磁盘操作,减少磁盘寻道时间,特别是在大量数据进行读写时。
  3. 页(Page):页是 InnoDB 存储数据的基本单元,标准大小为 16 KB,索引树上的一个节点就是一个页。也就意味着数据库每次读写都是以 16 KB 为单位的。
  4. 行(Row):InnoDB 采用行存储方式,意味着数据按照行进行组织和管理,行数据可能有多个格式,比如说 COMPACT、REDUNDANT、DYNAMIC 等。MySQL 8.0 默认的行格式是 DYNAMIC,由COMPACT 演变而来,意味着这些数据如果超过了页内联存储的限制,则会被存储在溢出页中。

25、MySQL 有哪些常见存储引擎?

MySQL 支持多种存储引擎,常见的有 InnoDB、MyISAM、MEMORY 等。
在这里插入图片描述

25.1 如何切换 MySQL 的数据引擎?

可以通过 alter table 语句来切换 MySQL 的数据引擎。不过不建议,应该提前设计好到底用哪一种存储引擎。

ALTER TABLE your_table_name ENGINE=InnoDB;

26、那存储引擎应该怎么选择?

  1. 大多数情况下,使用默认的 InnoDB 就对了,InnoDB 可以提供事务、行级锁、外键、B+ 树索引等能力。
  2. MyISAM 适合读更多的场景。
  3. MEMORY 适合临时表,数据量不大的情况。由于数据都存放在内存,所以速度非常快。

27、InnoDB 和 MyISAM 主要有什么区别?

InnoDB 和 MyISAM 之间的区别主要表现在:存储结构、事务支持、锁粒度、索引类型、主键必需、表的具体行数、外键支持等方面。

  1. 存储结构:
  • InnoDB:用两种格式的文件来存储,.frm 文件存储表的定义;.ibd 存储数据和索引。
  • MyISAM:用三种格式的文件来存储,.frm 文件存储表的定义;.myd 存储数据;.myi 存储索引。
  1. 事务支持:
  • InnoDB:支持事务。
  • MyISAM:不支持事务。
  1. 最小锁粒度:
  • InnoDB:行级锁,并发写入性能高。
  • MyISAM:表级锁,高并发中写操作存在性能瓶颈。
  1. 索引类型:
  • InnoDB 为聚簇索引,索引和数据不分开。
    在这里插入图片描述
  • MyISAM 为非聚簇索引,索引和数据分开存储,索引保存的是数据文件的指针。
    在这里插入图片描述
  1. 外键支持:
  • InnoDB:支持外键。
  • MyISAM:不支持外键。
  1. 主键必需:
  • InnoDB:必须有主键。
  • MyISAM:可以没有主键。
  1. 表的具体行数:
  • InnoDB:表的具体行数需要扫描整个表才能返回。
  • MyISAM:具体行数存储在表的属性中。

28、InnoDB 的 Buffer Pool了解吗?

Buffer Pool 是 InnoDB 存储引擎中的一个内存缓冲区,它会将数据以页(page)为单位保存在内存中,当有查询请求需要读取数据时,会优先从 Buffer Pool 获取数据,避免直接访问磁盘。也就是说,即便我们只访问了一行数据的一个字段,InnoDB 也会将整个数据页加载到 Buffer Pool 中,以便后续的查询。修改数据时,也会先在缓存页面中修改。当缓存中的数据页被修改后,会在 Buffer Pool 中变为脏页,不会立刻写回到磁盘。InnoDB 会定期将这些脏页刷新到磁盘,保证数据的一致性。通常采用 LRU 算法来管理缓存页,将最近最少使用的数据移出缓存,为新数据腾出空间。

Buffer Pool 能够显著减少对磁盘的访问,从而提升数据库的读写性能。调优上,我们可以设置合理的 Buffer Pool 大小(通常为物理内存的 70%),并配置多个 Buffer Pool 实例(通过 innodb_buffer_pool_instances)来提升并发能力。

29、待更新

30、


http://www.mrgr.cn/news/98155.html

相关文章:

  • 08-JVM 面试题-mk
  • UDS名词解释及分析
  • 【软考系统架构设计师】系统配置与性能评价知识点
  • 文件操作和IO - 2
  • 【零基础实战】Ubuntu搭建DVWA漏洞靶场全流程详解(附渗透测试示例)
  • 07-并发线程 面试题-mk
  • ssh 免密登录服务器(vscode +ssh 免密登录)
  • 【高性能缓存Redis_中间件】一、快速上手redis缓存中间件
  • C++基础精讲-02
  • 05-RabbitMQ 面试题-mk
  • 【软考系统架构设计师】信息安全技术基础知识点
  • Skynet入门(二)
  • TDengine 语言连接器(C/C++)
  • Windows系统Python多版本运行解决TensorFlow安装问题(附详细图文)
  • 用Java NIO模拟HTTPS
  • SDC命令详解:使用相对路径访问设计对象(current_instance命令)
  • 多线程(Java)
  • Ubuntu 系统深度清理:彻底卸载 Redis 服务及残留配置
  • 第十六届蓝桥杯省赛JavaB组题解
  • cdp-(Chrome DevTools Protocol) browserscan检测原理逆向分析