跳至内容

2026 年最全 34 道 MySQL 面试题与答案

通过这份面试题指南掌握 MySQL,结合真实示例与专家技巧,助您在下一次数据库面试中脱颖而出!
更新 2026年6月2日  · 15分钟

您是否注意到,几乎所有与数据库相关的岗位都要求会 MySQL?这是有充分理由的——从您常用的社交媒体平台到日常使用的应用程序,MySQL 几乎无处不在。

我整理了这份指南,帮助您攻克 MySQL 面试题。从初级开发者应掌握的基础,到高级岗位需要的复杂知识,我都会覆盖。此外,我还会分享一些技巧,帮助您在下一次与数据相关的面试中更自信地应对。 

什么是 MySQL?

MySQL 是一种基于 SQL 的开源关系型数据库管理系统(RDBMS),将数据组织为结构化的表。它由 Oracle Corporation 开发。

它在 2024 年被评为最受欢迎的 DBMS。不过,2025 年的 Stack Overflow 开发者调查显示,PostgreSQL 在专业开发者中首次超越 MySQL,成为使用最广泛的数据库。

别误会:MySQL 依然非常流行——2025 年开发者使用率达 40.5%——并且仍在支撑无数网络应用、内容管理系统与企业工具。尤其是当您从事 Web 应用或 LAMP 技术栈相关工作时,MySQL 仍是一项顶级技能。

图表显示 2024 年最流行的数据库系统,MySQL 名列第一,其次是 PostgreSQL。

2024 年,MySQL 是全球最受欢迎的开源 DBMS,排名分数为 1061。来源:Statista。

基础 MySQL 面试题

在初轮面试中,面试官可能会通过一些基础问题来评估您对数据库与 MySQL 核心概念的理解。 

1. 什么是数据库?它与 DBMS 有何不同? 

数据库是一个用于存储数据的容器,我们可以对其进行访问、修改和分析。比如,社交媒体平台会在数据库中存储哪些用户点赞了我们的帖子等数据。

DBMS(数据库管理系统)是一种软件,使我们能够与这些数据交互与管理它们,例如创建用户并管理其访问权限。MySQL 是最受欢迎的 DBMS 之一。其他示例包PostgreSQLMongoDBMicrosoft SQL Server

2. MySQL 与其他关系型数据库管理系统有何不同?

MySQL 是一种开源的关系型数据库管理系统(RDBMS),使用 SQL 管理数据。它以易用性、速度快以及与 Web 应用的良好兼容性而闻名。 

以下是 MySQL 与其他 RDBMS 的差异:

  • 简洁与性能: MySQL 常以简单易上手和优化过的性能著称,是 Web 开发者和初创团队的常用选择。
  • 高级特性: 虽然 MySQL 的易用性很强,但在某些高级特性上可能不及 PostgreSQL,例如更全面的 ACID 事务支持、更先进的索引以及更广泛的数据类型。
  • 存储引擎: MySQL 允许为表选择不同的存储引擎(如 InnoDB、MyISAM),从而针对特定场景灵活优化。

MySQL 适用于需要速度与可扩展性的场景;而若追求更复杂或企业级特性,PostgreSQL 可能更合适。

3. MySQL 提供的主要数据类型有哪些?

MySQL 支持多种数据类型,主要分为:

  • 数值型: INTDECIMALFLOATDOUBLE 等。

  • 字符串型: CHARVARCHARTEXTBLOB

  • 日期/时间: DATEDATETIMETIMESTAMPTIME

  • JSON: 用于存储 JSON 对象。

4. INT 与 DECIMAL 数据类型有什么区别? 

INT 存储不含小数点的整数,适用于不需要小数的场景。相反,DECIMAL 可存储金融金额,适合需要小数精度的计算。 

5. 在 MySQL 中,DATE 与 DATETIME 有何不同? 

MySQL 中的 DATE 以年、月、日的格式存储日期: 

YYYY-MM-DD

DATETIME 会存储日期与时间,如下所示: 

YYYY-MM-DD HH:MM:SS 

6. 什么是外键?在数据库中如何使用? 

外键是某个表中的字段,用于关联另一个表的主键。 

例如,在存储客户信息的 customers 表中,每位客户都有唯一的 customer_id——在另一个名为 transactions 的表(用于存储购买记录)中,我们将 customer_id 作为外键。transactions 表中的 customer_id 会将每笔购买关联到 customers 表中的特定客户。

以下是 SQL 示例:

CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100)
);
CREATE TABLE transactions (
    transaction_id INT PRIMARY KEY,
    customer_id INT,
    amount DECIMAL(10,2),
    date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

7. INNER JOIN、LEFT JOIN、RIGHT JOIN 与 FULL JOIN 有何区别?

连接用于基于相关列将两个或多个表的行组合。区别如下:

  • INNER JOIN: 返回两表中匹配的行。

  • LEFT JOIN: 返回左表的所有行以及右表中匹配的行;若无匹配,右表列返回 NULL

  • RIGHT JOIN: 类似 LEFT JOIN,但返回右表所有行以及与之匹配的左表行。

  • FULL JOIN:合并 LEFT JOINRIGHT JOIN 的结果,包含两表中未匹配的行。注意:MySQL 原生不支持 FULL JOIN 语法。要实现相同效果,可将 LEFT JOINRIGHT JOIN 的结果使用 UNION 进行合并。

8. 在 MySQL 中,DELETE、TRUNCATE 与 DROP 有什么区别?

DELETETRUNCATEDROP 看起来相似,但行为不同:

DELETE: 根据条件删除表中的行。若在事务中,可回滚。示例:

DELETE FROM employees WHERE department_id = 5;

TRUNCATE: 删除表中所有行,但保留表结构。它比 DELETE 更快,且不可回滚。示例:

TRUNCATE TABLE employees;

DROP: 完全删除表结构及数据,并移除索引等依赖。示例:

DROP TABLE employees;

9. 如何在 MySQL 中创建与修改表?请给出示例。

创建表使用 CREATE TABLE 语句,修改通常用 ALTER TABLE。示例如下:

创建表:

CREATE TABLE employees (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), department VARCHAR(50));

新增列:

ALTER TABLE employees ADD COLUMN salary DECIMAL(10, 2);

10. SQL 中的临时表是什么? 

临时表仅在当前数据库会话中存在。会话关闭后,表即被删除。它可用于临时存储中间结果,适合测试、筛选或在插入永久表前准备数据。

示例如下:

CREATE TEMPORARY TABLE temp_employees (
    id INT,
    name VARCHAR(50)
);
INSERT INTO temp_employees VALUES (1, 'John Doe');
SELECT * FROM temp_employees;

11. 什么是 MySQL 中的子查询?请举例说明。 

子查询(也称嵌套查询)是嵌套在另一条查询中的查询。它能将复杂操作拆分为更易管理的步骤。例如,您可以用子查询找出薪资高于平均值的员工: 

SELECT first_name, last_name, salary
FROM employees
WHERE salary > (
    SELECT AVG(salary)
    FROM employees
);

解析如下:

  1. 内部查询 SELECT AVG(salary) FROM employees 先计算平均薪资。

  2. 外部查询再据此找出薪资高于平均值的员工。 

12. 如何使用 MySQL 的 INSERT 语句向表中添加数据?有没有最佳实践? 

我们使用 INSERT 语句向表中添加数据。基本语法如下:

INSERT INTO table_name (column1, column2, ...) 
VALUES (value1, value2, ...); 

使用 INSERT 时的几条最佳实践:

  1. 显式列出列名。这样更清晰,也能在表结构变更时避免出错。

  2. 对于 AUTO_INCREMENT 列(如 ID),在 INSERT 语句中跳过它们。MySQL 会自动处理,避免重复 ID。 

  3. 字符串引号风格保持一致。我个人偏好单引号,但两者皆可。

  4. 插入多行时,尽量在一条语句中完成以获得更好性能。

13. MySQL 中 AUTO_INCREMENT 属性有什么作用?

AUTO_INCREMENT 属性用于为列(通常是主键)自动生成唯一的、递增的数值。

下面是创建带 AUTO_INCREMENT 列的表:

CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    department VARCHAR(50)
);

插入数据如下:

INSERT INTO employees (name, department) VALUES ('John Doe', 'Sales');
INSERT INTO employees (name, department) VALUES ('Jane Smith', 'Marketing');

14. MySQL 中的视图是什么? 

视图是一个已保存的查询,像虚拟表一样工作。借助视图,我们可以将复杂查询命名保存,后续像表一样直接使用,避免每次都重复书写完整查询。

例如,为简化查询员工详情及其部门名称,可以创建如下视图:

CREATE VIEW employee_details AS
SELECT 
    e.id,
    e.name,
    d.department_name,
    e.salary
FROM 
    employees e
JOIN 
    departments d ON e.department_id = d.department_id;

之后就可以像查询表一样使用 employee_details

SELECT * FROM employee_details;

不过,视图一般不用于插入或更新数据。大多数视图是只读的,并可限制用户直接访问底层数据,从而提升数据安全。需要注意的是,视图每次访问都会运行底层查询,可能会导致查询变慢。

进阶 MySQL 面试题

本节涵盖中级主题。这些问题主要用于考察您对 MySQL 数据类型与结构的理解。

15. 什么是系统版本表?它们如何工作? 

系统版本表会保留表中改动的完整历史。由于会保存每一行的先前版本,因此可用于审计与数据恢复。 

其原理是新增两列——StartTimeEndTime——记录每行的有效时间。当我们插入、更新或删除数据时,这些时间戳会被更新:

  • 插入: 新行的 StartTime 设为当前时间戳,EndTime 设为 9999-12-31 23:59:59——MySQL 的 DATETIME 最大值,用作“当前有效”的哨兵值。

  • 更新: 原行的 EndTime 更新为当前时间戳,标记其不再有效;随后创建一条包含更新后数据的新行,其 StartTime 为当前时间戳,EndTime 设为“永久”。

  • 删除: 将现有行的 EndTime 更新为当前时间戳,表示该行已不再有效。

借助 SQL 的 FOR SYSTEM_TIME 子句,您可以在特定时间点或时间范围内查询表的历史状态。例如:

  • FOR SYSTEM_TIME AS OF '2024-01-01':检索 2024-01-01 当日的表状态。

  • FOR SYSTEM_TIME BETWEEN '2024-01-01' AND '2024-12-31':显示在该时间范围内有效的所有行。

16. 什么是 MySQL 事务?如何使用?

事务是一组作为一个整体执行的操作。它们确保要么全部成功,要么全部失败,从而保证数据一致性。

示例:

START TRANSACTION;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 500 WHERE account_id = 2;
COMMIT; -- 将更改永久保存
-- 或者
ROLLBACK; -- 回滚更改

17. MySQL 中的默认约束是什么?如何为列设置默认值?

默认约束用于在执行 INSERT 时未提供显式值的情况下,为列赋予默认值。这可确保即使用户遗漏该列,数据仍然有效。

创建带默认值的表示例:

CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    status VARCHAR(10) DEFAULT 'active'
);

随后可在不指定 status 的情况下插入一行:

INSERT INTO employees (name) VALUES ('John Doe');

这种方式可降低关键列出现 NULL 或无效数据的可能性,并通过省去对默认情况的显式处理来简化查询。

字段

类型

可空

默认值

额外

id

INT

NO

PRI

NULL

AUTO_INCREMENT

name

VARCHAR(50)

YES

 

NULL

 

status

VARCHAR(10)

YES

 

active

 

该命令很有用,因为:

  • 可帮助开发者在写查询前了解表结构。
  • 调试时尤其有用,特别是在不熟悉的数据库中工作时。
  • 能快速识别约束,如主键或默认值。

18. MySQL 中 CHAR 与 VARCHAR 有何区别?

二者都存储字符串数据,但存储方式不同:

  • CHAR(n) 总是存储恰好 n 个字符,若不足则用空格填充。它是定长的,对于长度固定(如国家代码、状态标志)的列,通常稍快。

  • VARCHAR(n) 只存储实际输入的字符,最多不超过 n。对于变长数据更省空间,但会有记录长度的少量开销。

CREATE TABLE example (
    country_code CHAR(2),      -- Always 2 chars, e.g. 'US', 'UK'
    email VARCHAR(255)         -- Variable length up to 255 chars
);

经验法则:固定长度用CHAR,其他场景用VARCHAR

19. 如何在 SQL 中使用字符串函数处理文本? 

SQL 中的多种字符串函数可处理姓名等文本数据。例如:

  • 使用 LENGTH() 统计姓名字符数。 

  • UPPER()LOWER() 将文本转为全大写或全小写。 

  • CONCAT() 将名与姓拼接为一列。 

  • SUBSTRING() 提取文本的特定部分,例如可用来从生日中分离月份。 

示例查询:

SELECT 
    UPPER(first_name) AS upper_name,
    CONCAT(first_name, ' ', last_name) AS full_name,
    SUBSTRING(birthdate, 6, 2) AS birth_month,
    TRIM(last_name) AS trimmed_last_name,
    REPLACE(first_name, 'a', '@') AS replaced_name
FROM employees;

该查询将:

  • 把姓名转为大写。

  • 将名与姓组合为全名。

  • birthdate 列中提取出生月份。

  • 去除姓氏中的空格。

  • 将名字中所有的 "a" 替换为 "@"。

20. 如何用 SQL 更新数据库中的特定行?

可以使用 UPDATE 语句并配合 WHERE 子句定位要修改的记录。 

例如,将 2010 年电影“Inception(盗梦空间)”的类型更新为“Sci-fi(科幻)”,可以这样写: 

UPDATE movies
SET genre = 'Sci-Fi'
WHERE movie_title = 'Inception' AND year = 2010;

其中,UPDATE movies 指定要更新的表,WHERE 子句锁定标题为“Inception”且年份为“2010”的行。 

高级 MySQL 面试题

高级问题考察您处理复杂 MySQL 场景的能力,并让面试官了解您的技术决策能力。 

21. 什么是 MySQL 触发器?如何实现? 

在 MySQL 中,触发器是在发生特定数据库事件时自动运行的一组操作。触发器可配置为在 INSERTUPDATEDELETE 等事件之前或之后执行。 

例如,设有一个新增订单的 orders 表。我们可以创建一个触发器,将每条新订单记录到 order_history 表中:

CREATE TRIGGER after_order_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
    INSERT INTO order_history (order_id, action, timestamp)
    VALUES (NEW.order_id, 'inserted', NOW());
END;

触发器运行后,order_history会自动更新:

history_id

order_id

action

timestamp

1

1

inserted

2024-12-24 10:00:00

2

2

inserted

2024-12-24 11:00:00

22. 为什么添加索引会让 SQL 查询更快? 

如果没有索引,数据库需要逐行扫描以找到目标记录。索引用于像目录一样 帮助数据库快速定位相关行。因此,添加索引可缩短搜索时间,让查询更快。 

索引通常基于 B-tree 或哈希表等数据结构实现,使数据库能高效执行搜索、查找与范围扫描。

创建索引示例:

-- 未建索引:
SELECT * FROM employees WHERE last_name = 'Smith';
-- 在 last_name 列上添加索引:
CREATE INDEX idx_last_name ON employees(last_name);
-- 有了索引,数据库可以快速定位 last_name 为 'Smith' 的行。

索引也有一些代价,例如:

  • 写入变慢: INSERTUPDATEDELETE 操作会变慢,因为每次数据变更都需要更新索引。

  • 存储开销: 索引需要额外的存储空间。

23. 在 SQL 表中,产品的重量与价格应使用哪种数据类型?为什么? 

对于重量,一般更安全的选择是 DECIMAL。虽然 FLOATREAL 也能存储小数,但它们使用浮点运算,可能引入微小的舍入误差。

对于需要准确性的产品重量(如运费计算、库存),DECIMAL(8, 3) 可提供 3 位小数的精确控制,避免舍入问题。只有在允许小误差时,FLOAT 才可接受。

24. 如何使用窗口函数在 SQL 中查找重复行? 

可使用 ROW_NUMBER() 窗口函数查找重复项:

WITH DuplicateCheck AS (
    SELECT product_name, 
           category,
           ROW_NUMBER() OVER(
               PARTITION BY product_name, category 
               ORDER BY id
           ) AS row_num
    FROM sales
)
SELECT *
FROM DuplicateCheck
WHERE row_num > 1;

工作原理如下:

1. ROW_NUMBER() 为结果集中的每一行编号。 

2. PARTITION BYproduct_namecategory 分组。 

3. 每组内从 1 开始编号。 

4. 编号大于 1 的即为重复项。 

例如,若有如下记录:

  • Product A、Category X,row_num = 1
  • Product A、Category X,row_num = 2(重复)
  • Product B、Category Y,row_num = 1

查询将返回第二行,因为其 row_num 大于 1。

25. 如何在 MySQL 中创建与使用带参数的存储过程?请举例说明。 

我们可以通过存储过程保存并复用复杂查询,从而提升数据库操作的效率与可维护性。下面用一个实际例子说明如何创建并使用带参数的存储过程。

假设我们有一个学生数据库,希望创建一个过程按年龄筛选学生。可按如下方式实现:

首先,创建一个接收年龄参数的简单存储过程:

CREATE PROCEDURE get_student_info(IN age INT)
BEGIN
    SELECT * FROM student WHERE student.age = age;
END;

调用该过程时,只需用目标年龄进行 CALL

CALL get_student_info(21);

还可以使用输出参数让过程更强大。例如,创建一个统计特定年龄学生数量的过程:

CREATE PROCEDURE count_students_by_age(IN age INT, OUT student_count INT)
BEGIN
    SELECT COUNT(*) INTO student_count FROM students WHERE students.age = age;
END;

获取结果:

SET @count = 0;
CALL count_students_by_age(21, @count);
SELECT @count AS total_students;

26. 为什么参照完整性在数据库中很重要? 

参照完整性能保证表之间的关系准确。创建外键后,可确保某表中的值与被引用表中的唯一值相匹配。

举例:在电商数据库中,您有 Customers 表与 Orders 表。每个订单都必须属于一个真实的客户。通过外键实现的参照完整性会强制如下规则:

  • 无法为不存在的客户创建订单。
  • 无法删除仍有关联订单的客户(除非您明确配置对这些订单的处理方式)。
  • 无法更新已有关联订单的客户 ID。

当您创建如下外键约束:

ALTER TABLE Orders
ADD FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID);

数据库会自动强制这些规则:

  • Orders 表中的每个 CustomerID 必须存在于 Customers 表中。

  • 任何试图违反这些规则的操作(如插入无效的 CustomerID)都会被拒绝。

这可防止数据不一致带来的严重问题,例如无法将订单追溯到实际客户,或报表中缺失客户信息等。 

面向数据库管理员的 MySQL 面试题

如果您应聘的是数据库管理员职位,以下是招聘方可能会问到的一些问题。

27. 为什么大型应用要使用分片?同时谈谈其挑战。 

大型应用通过数据库分片将海量数据拆分到多个服务器上。每个分片包含一部分数据。通过分散负载,无需高端硬件;同时性能与可扩展性也会提升。但也存在一些挑战: 

  • 某些查询(如跨分片的连接)可能难以实现,从而复杂化数据管理。 
  • 数据增长后,个别分片可能成为热点,导致性能下降。 

28. 解释 MySQL 崩溃恢复中 redo 日志的作用。 

每次 MySQL 修改数据,都需要写入磁盘。但直接写数据文件既慢又有风险。因此,在修改任何数据文件之前,MySQL 会先将将要执行的更改写入 redo 日志。这比直接随机更新数据文件更安全。

例如,您更新某客户的地址:

  1. MySQL 首先将该更改写入 redo 日志。
  2. 随后确认事务提交成功。
  3. 最终再将更改应用到实际数据文件。

崩溃恢复在 MySQL 在第 1 或第 2 步之后、第 3 步之前崩溃时尤为重要。重启后,MySQL 会读取 redo 日志并重放其中记录的更改,完成未完成的工作。这确保了已提交的事务不会丢失,即使崩溃发生在不合时宜的时刻。

29. MySQL 提供了哪些不同的存储引擎?它们有何区别?

MySQL 支持多种存储 引擎,每种都针对不同场景优化。以下是常见引擎的对比:

存储引擎 关键特性 最佳适用场景
InnoDB 默认引擎。ACID 事务、行级锁、支持事务与外键。 电商、金融系统、任何需要数据一致性的场景。
MyISAM 读取快,表级锁。不支持事务与外键。 读多写少、对一致性要求不高但追求速度的应用。
Memory 数据存于内存。极快,但重启即失。 缓存、会话管理、临时数据。
CSV 以纯 CSV 文件存储数据。不支持索引。 应用间数据交换或简单平面文件存储。
Archive 高压缩。仅支持 INSERT 与 SELECT。无索引。 日志或很少查询的历史数据。
NDB(集群) 分布式存储,高可用、容错,支持事务。 需要实时性能的大规模分布式应用。

30. 如何设置 MySQL 的默认存储引擎? 

首先,可查看当前默认存储引擎:

SHOW ENGINES;

建议将 InnoDB 设为默认引擎,因为它支持以下关键特性:

  • 符合 ACID 的事务
  • 外键约束
  • 崩溃恢复
  • 行级锁

要在当前会话中临时更改默认引擎,可用:

SET default_storage_engine = 'InnoDB';

若需永久更改,可在 MySQL 配置文件的 [mysqld] 部分添加:

default-storage-engine = InnoDB

31. 如何修复 MySQL 中损坏的表? 

首先,可使用以下命令检查所有数据库: 

mysqlcheck --check --all-databases -u root -p

它会扫描所有表并报告是否有损坏。随后可运行以下命令修复表: 

mysqlcheck --repair database_name table_name -u root -p

修复可能在严重损坏时导致数据丢失,请务必先备份数据。

情景与问题解决类 MySQL 面试题

这类问题考察您处理真实复杂场景的经验与问题解决能力。

32. 说明一个您使用 MySQL 子查询的场景。

您可以这样回答:

我在上一份工作中负责一个电商商店的数据库,需要制作一份产品报告。目标是找出销售额高于平均水平的产品,这需要使用子查询完成多步分析。

为此我编写了如下 SQL:

SELECT 
    p.product_id,
    p.product_name,
    s.sales_amount
FROM products p
JOIN sales s ON p.product_id = s.product_id
WHERE s.sales_amount > (
    SELECT AVG(sales_amount)
    FROM sales
)
ORDER BY s.sales_amount DESC;

我首先通过一个子查询计算所有产品的平均销售额,作为基线。该子查询位于 WHERE 子句中,用来动态生成阈值,以衡量每个产品的表现。

主查询连接 products 与 sales 表获取产品详情,并借助 WHERE 子句过滤掉低于平均水平的产品。 

通过这种写法,我可以用一次数据库操作就识别出高表现产品,而无需多次单独查询。

33. 说明一个您使用 SQL 连接合并多表数据的场景。 

可参考如下回答:

前不久我参与的一个项目,有两张核心表——一张是产品销量数据,另一张是产品详情。我的任务是创建一份报告,展示 salesproduct namecategoryprice

我使用 INNER JOIN 基于公共列 product_id 将销售记录与产品详情关联:

SELECT 
    s.sales_date,
    p.product_name,
    p.category,
    s.quantity_sold,
    p.price
FROM 
    sales s
INNER JOIN 
    products p
ON 
    s.product_id = p.product_id;

该报告清晰呈现了销量趋势,帮助相关方识别表现良好的产品品类以及需要优化的方向。

34. 您是否有触发器方面的经验?请说明您的实践。

可参考如下回答:

是的,我在数据库触发器方面有较多经验。最近的工作中,我实现了一个用于价格变更审计的 AFTER UPDATE 触发器。 

具体实现如下:我创建了一个触发器,在产品价格发生变更时自动记录价格历史。以下是我编写的 SQL:

CREATE TRIGGER tr_AuditPriceChanges
AFTER UPDATE ON Products
FOR EACH ROW
BEGIN
    -- Only log if the price actually changed
    IF OLD.UnitPrice <> NEW.UnitPrice THEN
        INSERT INTO PriceAudit (
            ProductID,
            OldPrice,
            NewPrice,
            ChangedBy,
            ChangeDate,
            PercentageChange
        )
        VALUES (
            NEW.ProductID,
            OLD.UnitPrice,
            NEW.UnitPrice,
            CURRENT_USER(),
            NOW(),
            ROUND(((NEW.UnitPrice - OLD.UnitPrice) / OLD.UnitPrice * 100), 2)
        );
    END IF;
END;

该方案的亮点在于:

  1. 仅在价格确实变更时触发。
  2. 使用 SYSTEM_USER 捕获执行变更的用户。
  3. 计算价格变动百分比,便于报表分析。
  4. 包含 WHERE 条件以过滤由于其他列更新导致的“无变更”情况。

我们还在遇到 NULL 价格的边界情况时加入了错误处理与日志记录。

MySQL 面试准备技巧

如果您刚开启职业生涯,以下建议有助于您在面试中脱颖而出:

掌握 MySQL 核心概念:数据库基础,如索引、事务与查询优化器。理解 MySQL 如何处理查询与管理存储。这有助于您写出高效查询并在面试中清晰阐述思路。

动手实践: 在本地安装 MySQL 并持续练习。创建测试数据库,编写不同类型的查询并尝试优化。真实动手是理解原理与建立自信的最佳方式。

若想进一步巩固知识,欢迎查看 DataCamp 的资源: 

了解 MySQL 工具与集成: 熟悉 MySQL Workbench 或其他数据库管理与基础监控工具。您也可以了解 MySQL 如何与 Python 协作 及相关框架,展现您具备真实开发环境下的协作能力。

结语

以上就是全部内容!我为您整理了 34 道 MySQL 面试高频题,助您斩获下一份工作。无论是入门岗位还是高级数据库管理员职位,扎实掌握 MySQL 基础、查询优化与数据库管理,都是让您脱颖而出的关键。 

想要扩展对其他数据库管理系统的了解,欢迎查看 DataCamp 的 SQL 课程

主题

用这些课程进一步学习 SQL!

Courses

SQL 中的数据处理

4小时
324.1K
掌握复杂的 SQL 查询,解答各种数据科学问题,并在 PostgreSQL 中准备稳健的数据集用于分析。
查看详情Right Arrow
开始课程
查看更多Right Arrow