MySQL 技能评估题库全解析:linkedin-skill-assessments-quizzes 中 157 道核心考点精讲
MySQL 技能评估题库全解析:linkedin-skill-assessments-quizzes 中 157 道核心考点精讲
本指南以本仓库 mysql/mysql-quiz.md 收录的 157 道 MySQL 技能评估真题为骨架,系统梳理 MySQL 的建表与数据类型、查询与过滤、JOIN 与子查询、存储过程与触发器、事务与权限、备份恢复、JSON 处理等核心知识点。读完本文,你将能独立厘清 MySQL 的高频考点与易错概念(如 DROP 与 TRUNCATE、WHERE 与 HAVING、UNION 与 UNION ALL 的差异),并为面试或备考提供一份可复现、可背诵的实战速查手册。
说明:该题库以 Markdown 问答形式组织,每题以
#### Qn编号,正确答案以<a href="https://link.gitcode.com/i/4e9f7bc0b045d61155fbf8a42db524b5" target="_blank">x]标记。仓库还提供了德语 [mysql/mysql-quiz-de.md 与乌克兰语 mysql/mysql-quiz-ua.md 两个翻译版本,可与英文版对照学习。
一、题库全景与使用方式
该题库覆盖了 MySQL 从入门到进阶的完整知识面,按主题可划分为以下板块:
| 主题板块 | 代表题目 | 核心能力 |
|---|---|---|
| 建表与数据类型 | Q7、Q8、Q66、Q78、Q92、Q129、Q131 | 掌握 CREATE TABLE、ENUM、DECIMAL、UNSIGNED、AUTO_INCREMENT |
| 查询、过滤与排序 | Q20、Q23、Q25、Q27、Q108、Q149 | 掌握 SELECT、WHERE、LIKE、BETWEEN、DISTINCT、LIMIT |
| JOIN 与外键建模 | Q40、Q54、Q60、Q88、Q94、Q113 | 掌握 LEFT/RIGHT/INNER JOIN 与表关系设计 |
| 子查询、CTE 与窗口函数 | Q1、Q35、Q47、Q55、Q84、Q154 | 掌握 IN 子查询、WITH 公共表表达式、WINDOW 子句 |
| 存储过程与函数 | Q6、Q70、Q76、Q95、Q96 | 掌握 CREATE PROCEDURE、参数模式、CASE 分支 |
| 触发器与事件 | Q24、Q38、Q82、Q100、Q110、Q111 | 掌握触发器事件、NEW/OLD 伪记录、全文索引 |
| 事务与一致性 | Q90、Q144、Q155 | 掌握 START TRANSACTION、COMMIT、ROLLBACK 与原子性 |
| 权限与安全 | Q14、Q37、Q45、Q53、Q136 | 掌握 ACL 授权模型、GRANT、SHOW GRANTS |
| 命令行工具与备份恢复 | Q2、Q4、Q31、Q36、Q64、Q93 | 掌握 mysqldump、mysql、mysql_upgrade、perror |
| JSON 与半结构化数据 | Q39、Q65、Q157 | 掌握 JSON 列、->> 提取、JSON_TABLE() |
| 数据库设计规范化 | Q69、Q97、Q56 | 掌握范式化、冗余与去重设计 |
每道题在原文中均附有正确/错误选项的辨析,部分题还带有 Reference] 注释与图表演示(集中在 [mysql/images 目录),适合先自测再对照解析的学习方式。
二、建表、数据类型与约束
1. 正确的建表语法(Q8、Q43)
管理岗要求构建员工表时,正确的语法要点有二:一是 CREATE TABLE IF NOT EXISTS 可避免“表已存在”报错;二是主键约束必须写成 PRIMARY KEY (employeeID) 的列级/表级语法,而非 PRIMARY KEY employeeID 或 PRIMARY KEY ON employeeID:
CREATE TABLE IF NOT EXISTS employee (
employeeID char(10),
firstName varchar(50),
lastName varchar(50),
phone varchar(20),
address varchar(50),
PRIMARY KEY (employeeID)
);
批量插入多行时,正确写法是一组 VALUES 后以逗号分隔多行数据,而不是重复写多个 values 关键字(Q43):
INSERT INTO cars (make, model, year) VALUES
('Ford', 'Mustang', 2002),
('Mercedes', 'C', 2003);
2. 字符串类与枚举类型(Q7、Q79、Q92)
- 存储学生成绩(A/B/C/D/F)这类取值固定且有限的场景,
ENUM是最佳选择(Q7)。其正确声明语法为name ENUM('Small','Medium','Large'),即“列名在前、ENUM 取值列表在后”(Q92)。 - MySQL 的字符串类型包括
CHAR、VARCHAR、ENUM、SET等,而BIT属于位字段(二进制)类型,不是字符串类型(Q79)。 - 如果 ID 字段需要容纳字母或保留前导零,选择
CHAR(10)而非INT是合理的;但“CHAR(10)比 INT 更节省空间”这一说法不成立——定长字符类型在字节占用上并不优于整数(Q83)。
3. 数值、布尔与自增(Q78、Q129、Q131、Q98)
- 货币价格字段建议使用
DECIMAL(10,2):它同时限定总位数(10 位)与小数位数(2 位),避免FLOAT/DOUBLE的浮点舍入误差(Q78)。 UNSIGNED修饰符使整型列不再存储负数,从而把可存储的最大值翻倍(如TINYINT UNSIGNED范围从 -128~127 变为 0~255)(Q129)。AUTO_INCREMENT用于为每一行自动生成唯一标识,通常配合主键使用(Q131)。- 修改已有行的数据用
UPDATE ... SET ... WHERE ...,例如UPDATE Item SET endOfLife = true WHERE makeYear < 2019(Q98)。
4. 约束与索引的基础认知(Q3、Q30、Q72、Q116)
- 限制列内数据类型取值范围的约束属于列级约束(column level),例如
NOT NULL、UNIQUE、CHECK等(Q3)。 - 设计良好的关系表中,每张表都应具备主键(primary key),用于唯一标识每一行(Q30)。
PRIMARY KEY的本质是在表上创建一个唯一索引(Q116)。 - 单个表索引最多可以包含 16 列(Q72,该上限同时受索引长度限制约束)。
UNIQUE约束保证列内所有值互不相同(Q141),CREATE INDEX用于显式创建索引(Q142)。
三、核心查询:SELECT、过滤、排序与去重
1. SELECT 基础(Q21、Q29、Q115、Q124)
SELECT * FROM clients;中clients代表一张表(Q21)。- 选取某表全部行:
SELECT * FROM inventory;(Q29)。 - SQL 全称是 Structured Query Language(Q114),而 MySQL 是关系型数据库管理系统(RDBMS),用来管理 SQL 数据库(Q22);MySQL 本身是**客户端/服务器(client and server)**架构的数据库系统(Q12)。
2. 过滤:WHERE、LIKE、BETWEEN、IN(Q19、Q20、Q108、Q9)
WHERE用于按行过滤;LIKE用于模式匹配;LIMIT用于限制返回行数。GROUP BY不是过滤语句,它负责分组聚合(Q19、Q112)。SELECT * FROM Employees WHERE EmployeeName LIKE 'a%'返回 EmployeeName 以 "a" 开头的记录——%匹配任意长度的字符序列(Q20)。LIKE运算符的用途就是在列中搜索指定模式(Q133)。- 需要选择“在某个取值集合内”的记录时使用
IN子句,例如根据 customerID 集合筛选购买了特定车型的客户(Q9)。 BETWEEN ... AND ...用于选取闭区间内的记录:SELECT * FROM Persons WHERE LastName BETWEEN 'Hansen' AND 'Pettersen'(Q108)。
3. 排序、去重与限量(Q23、Q27、Q25、Q127、Q149)
- 按名称排序影片表:
SELECT * FROM movies ORDER BY name;——ORDER BY是排序子句,GROUP BY、FILTER BY均不能用于排序(Q23)。 - 去除重复行:
DISTINCT关键字,用于 SELECT 结果集去重(Q27、Q149)。 - 防止超大结果集:
LIMIT限制返回行数(Q25、Q127)。 - 聚合计数时配合
DISTINCT可统计不重复值:COUNT(DISTINCT column)。
4. 聚合函数与 HAVING(Q99、Q103、Q104、Q105、Q135、Q152)
COUNT()是典型的聚合函数(aggregate function),与NOW()、MID()、FORMAT()这类标量/字符串函数相区别(Q99、Q103)。HAVING用于对分组或聚合结果进行过滤(Q135、Q152),通常与GROUP BY搭配;WHERE则在分组前过滤行。二者“相似”但作用阶段不同(Q105)。- 例如按州统计购车客户数并只显示超过 100 人的州:
SELECT state, COUNT(*)
FROM customers c
JOIN purchases p ON c.ID = p.customerID
GROUP BY state
HAVING COUNT(*) > 100;
四、JOIN、外键与表关系建模
1. JOIN 类型辨析(Q88、Q113、Q94、Q107)
LEFT JOIN(即LEFT OUTER JOIN)返回左表全部行,右表无匹配时以NULL填充(Q113)。同理,RIGHT JOIN保留右表全部行;INNER JOIN只返回两表都匹配的行。- 左/右连接统称为外连接(Outer Join)(Q88、Q121)。
- 需要列出“所有汽车,无论是否已售出”时,应以
cars为左表做LEFT JOIN purchases(Q94):
SELECT cars.*, purchases.date
FROM cars LEFT JOIN purchases
ON cars.ID = purchases.carID;
- 一个典型的错误 JOIN 写法:
ON e.dept_id = e.dept_id两侧引用了同一张表的同一列,条件恒真,属于逻辑错误(Q107)。正确写法是ON e.dept_id = d.dept_id。
2. 三表 ER 图与外键(Q40、Q54、Q60、Q80、Q9)
题库中的多张图表题围绕 customers、purchases、cars 三张表展开(图示见 mysql/images/mysql_q09.jpg、mysql/images/mysql_q61.png):
customers.ID与cars.ID是主键;purchases.customerID通过外键引用customers.ID,purchases.carID通过外键引用cars.ID。因此purchases.customerID是引用 customers.ID 的外键(Q40),而非主键。- 员工表与职位薪资历史表通过
employeeID连接时,employment.employeeID是外键(foreign key)(Q54)。 customers与cars通过purchases中间表形成的联系是**多对多(many-to-many)**关系(Q80)。
3. 多表聚合查询(Q60、Q87、Q109)
- 统计“每位客户所在州售出的汽车数量”,需要三表/两表连接后再分组。正确写法(隐式内连接 +
GROUP BY state):
SELECT state, COUNT(*)
FROM customers c, purchases p
WHERE c.ID = p.customerID
GROUP BY state;
若改用 LEFT JOIN,未产生购买记录的客户也会被计数,导致结果偏大(Q60 解析)。
- 需要“每种 make/model 的价格小计 + 各 make 汇总 + 全体总计”时,使用
GROUP BY ... WITH ROLLUP(Q87、Q153)——它是GROUP BY的扩展,自动生成分组小计与总计行。 - 多表联合查询的语义题:
Students、Courses、Grades三表按Roll_number、Course_number、Instructor='Sriram'、Grade='A'连接后取DISTINCT Name,得到的是在 Sriram 所授课程中至少获得一个 A 的学生名单(Q109)。
五、子查询、CTE 与窗口函数
- 子查询执行顺序:含子查询的语句中,子查询先执行,其结果再供主查询使用(Q1)。
- SELECT 子句中的子查询必须返回单个值(标量子查询),才能作为结果列输出(Q35)。
- 需要运行递归子查询但又不想创建存储过程时,用
WITH子句(Q47)。MySQL 8.0+ 的 CTE 声明语法为:
WITH cte AS (SELECT id FROM users) SELECT ... FROM cte;
注意 WITH 在 AS 之前、SELECT 之前,不能写成 WITH (SELECT ...) as cte(Q55)。
- CTE 的用途是把复杂查询拆解成可读的片段并在同一条查询内复用(Q84)——它不创建临时表,也不跨查询存活。
- MySQL 8.0 的
WINDOW子句可以为窗口函数命名并复用窗口规格(分区、排序、帧定义),提升分析型查询的可读性(Q154)。
六、存储过程与存储函数
- 创建存储过程的正确语法(Q6):过程名后跟
(),主体以BEGIN ... END包裹,且不需要AS:
CREATE PROCEDURE P ()
BEGIN
END
- 存储例程(procedure/function)内部不能使用
USE语句切换数据库,但可以使用SELECT、SET、DECLARE等(Q81)。 - 存储过程参数有三种模式:
IN(输入)、OUT(输出)、INOUT(输入输出);IN OUT(带空格)不是合法模式(Q70)。 - 当一个条件分支针对同一个变量的多个取值做判断时,更适合改写成
CASE语句(Q95)——例如IF var1 = 1 ... ELSEIF var1 = 2 ...这类结构。 - 存储函数(stored function)的用途是:在 SQL 查询中对列套用公式与业务规则,以及复用反复出现的查询逻辑(Q96)。
- 安全方面,存储过程的意义在于应用只被授予过程执行权限、而无须暴露底层表,从而提升安全性(Q76)。
七、触发器、视图与全文索引
1. 触发器基础(Q24、Q38、Q82、Q100、Q110)
- 触发器与表关联,由 INSERT、UPDATE、DELETE 三种事件激活(Q24)。
- 临时表(temporary table)不能关联触发器(Q38);此外触发器不支持
IF EXISTS或CROSS JOIN这类写法(Q110)。 - 新增学生记录时,希望在 Exam、Score、Attendance 等关联表自动创建记录——用触发器实现(Q82)。
- 在
UPDATE触发器内访问新地址值,应使用NEW.address(Q100);OLD用于访问旧值。插入类校验(如保证 purchases.customerID/carID 必须存在于对应表)应使用BEFORE INSERT触发器(Q110)。
2. 视图(Q48、Q89、Q122)
- 创建视图的合法语法是
CREATE VIEW v1 AS SELECT * FROM t1;——AS后直接跟 SELECT,不需要BEGIN/END(Q89、Q122)。 - 视图的三种处理算法是 MERGE、TEMPTABLE、UNDEFINED;
updatable(可更新)是视图的属性而非处理算法(Q48)。
3. 全文索引与全文检索(Q67、Q111)
- 对
description列启用全文索引:ALTER TABLE car ADD FULLTEXT(description)(Q111)。 - 全文检索使用
MATCH(address) AGAINST ('street, drive')语法,而非WHERE address MATCH ...或MATCH(...) IN (...)(Q67):
SELECT * FROM customers
WHERE MATCH(address) AGAINST ('street, drive');
八、事务、数据导入导出与数据清理
1. 事务控制(Q90、Q144、Q155)
- 开启事务用
START TRANSACTION(Q144)。 - 事务内发生异常时执行
ROLLBACK回滚,配合COMMIT提交,保证原子性——要么全部成功,要么全部不生效(Q90、Q155)。 - 事务是“把多条 SQL 作为单一单元执行、出错时可整体回滚”的机制(Q155)。
2. 数据导入:LOAD DATA 与 LOAD XML(Q41、Q57)
- 从文件加载数据到表:
LOAD DATA INFILE(或LOAD DATA LOCAL INFILE读取客户端本地文件)(Q41)。 LOAD XML LOCAL INFILE 'cars.xml' INTO TABLE cars ROWS IDENTIFIED BY '<car>';支持的 XML 结构包括:<car><field name="make">...</field></car>(字段名由name属性给出)、<car make="Ford" model="Mustang" year="2002"/>(属性即列值)、<car year="2010"><make>Mercedes</make>...</car>(子元素即列值)。不支持把多个<car>元素拆散为“一个元素对应一个字段”的写法(Q57,选项 B)。
3. 数据清理与去重(Q58、Q61)
- 插入时忽略重复行:
INSERT IGNORE——遇到违反唯一性约束的行时发出警告并跳过(Q58)。 - 迁移数据时删除重复行,最佳实践是
DELETE JOIN:自连接后删除重复记录(Q61)。
4. 表操作辨析:DROP / TRUNCATE / DELETE(Q28、Q59、Q118、Q132、Q150)
| 操作 | 效果 | 触发器 | 可否带 WHERE |
|---|---|---|---|
DROP TABLE |
删除表连同其定义(Q28、Q132) | — | 否 |
TRUNCATE TABLE |
清空所有行但保留表定义(Q150);实现上先 DROP 再重建表,不触发 DELETE 触发器(Q59) | 不触发 | 否 |
DELETE FROM ... WHERE |
逐行删除,可带条件(Q118) | 触发 | 是 |
- 删除单条记录的正确语法是
DELETE FROM table ...,不存在REMOVE(Q18)。 - 与临时表同名的工作场景:重建成同名的临时表前,先执行
DROP TEMPORARY TABLE customers;(Q46)。
九、JSON 与半结构化数据
MySQL 5.7+ 提供原生 JSON 数据类型,相关考点包括:
- JSON 列的一个主要缺点是无法直接建立索引——对 JSON 字段的检索通常需要借助生成列或
->>提取后的虚拟列(Q39)。 - 从 JSON 列中提取字段值:
SELECT city->>'$.name' city FROM json_data;——->>返回去引号的文本值;->则返回带引号的结果(Q65)。 - MySQL 8.0 的
JSON_TABLE()函数把 JSON 文档映射为关系型行列,从而可以用标准 SQL 查询半结构化数据(Q157)。
十、权限、安全与账户管理
- MySQL 基于**访问控制列表(ACL)**实现所有连接与操作的安全控制(Q14)。
- 查看某账户的具体权限:
SHOW GRANTS(显示分配给账户/角色的权限与角色);SHOW PRIVILEGES则是列出服务器支持的全部系统权限(Q37)。 - 用户账户密码存储在 mysql.user 系统表中(Q53)。
- 授予权限用
GRANT语句(Q136);mysqladmin reload等价于mysqladmin flush-privileges(Q75)。 - 安全加固的“反面教材”:不要以 Unix root 用户运行 MySQL 服务器,不应把 PROCESS/SUPER 权限授给普通用户(Q45)。
- 显示当前用户与主机:
SELECT USER()(Q138);CURRENT_USER()也可获取当前账户名(Q148)。
十一、命令行工具、选项文件与备份恢复
1. 客户端/服务器命令行工具族(Q4、Q5、Q12、Q31、Q49)
- 大多数 MySQL 命令行程序用
--help查看各选项说明(Q4);-h通常指主机名。 - Shell 通过环境变量
PATH定位 MySQL 程序(Q5)。 - 选项文件(option file)即配置文件,用于集中声明常用选项,免去每次在命令行重复输入(Q31)。
- 程序选项修饰符
--loose让程序在遇到无法识别的选项时仅发警告而不退出报错(Q85)。 perror工具用于显示系统错误码与存储引擎(表处理器)错误码的含义(Q49)。
2. 导出、备份与恢复(Q2、Q32、Q33、Q34、Q63、Q64、Q93)
- 导出整个数据库(含对象定义与数据)用
mysqldump(Q2);但mysqldump的输出格式不支持 JSON(支持 CSV、XML、TXT 等文本格式)(Q93)。 - 安装后可能需要初始化数据目录(data directory),部分安装方式会自动完成(Q32)。
- 复制(replication)以 master-slave(主从) 配置在多个服务器上维护相同数据(Q34)。
- 备份类型辨析:包含自上次全量备份以来所有变更的是差异备份(differential);只包含上次备份(全量或增量)之后变更的是增量备份(incremental)(Q63)。
- 升级后执行
mysql_upgrade:发现潜在不兼容的表时,会执行表检查,发现问题则尝试修复(Q36)。 - 恢复数据库时,先重建数据库,再用
mysql客户端导入备份文件(Q64)——例如mysql -u root -p dbname < backup.sql。 - 导出 CSV 且首行带列头:常借助
SELECT ... UNION ...拼接列名行与数据行,再配合SELECT ... INTO OUTFILE输出(Q33)。
3. 表结构与元数据查看(Q13、Q50、Q51、Q68、Q73、Q44、Q139、Q156)
| 需求 | 命令 |
|---|---|
| 查看表结构 | DESCRIBE table;(等价于 SHOW COLUMNS FROM table;)(Q13、Q50、Q120) |
| 列出当前库所有表 | SHOW TABLES;(Q51) |
| 列出服务器上所有数据库 | SHOW DATABASES;(Q68、Q128) |
| 列出当前库的触发器 | SHOW TRIGGERS;(Q73) |
| 获取建表语句(含列与索引,用于克隆表) | SHOW CREATE TABLE;(Q44) |
| 查看 SELECT 执行计划 | EXPLAIN(Q139);MySQL 8.0.18+ 的 EXPLAIN ANALYZE 会真实执行查询并输出实际执行时间与计划(Q156) |
表维护语句包括 CHECK TABLE、ANALYZE TABLE、OPTIMIZE TABLE;CREATE TABLE 不属于表维护语句(Q52)。
十二、函数速查与易错点辨析
1. 常用函数速查表(Q91、Q125、Q130、Q134、Q137、Q140、Q143、Q145、Q102)
| 函数 | 作用 |
|---|---|
CURDATE() |
当前日期(Q91) |
NOW() |
当前日期与时间(Q125) |
LENGTH() |
字符串长度(Q130) |
ROUND() |
四舍五入到最近整数(Q140) |
IFNULL(expr, val) |
表达式为 NULL 时返回指定值(Q137) |
COALESCE(...) |
返回参数列表中第一个非 NULL 值(Q143) |
CONCAT(...) |
拼接两个或多个字符串(Q145) |
UPPER() |
转为大写,可用于大小写不敏感比较(Q102) |
ROW_COUNT() |
返回 INSERT/UPDATE/DELETE 影响的行数(Q134) |
REGEXP(运算符) |
按正则表达式做模式匹配(Q147),如 name REGEXP '^to' 返回以 "to" 开头的名字(Q86) |
用正则校验 email 格式也是 REGEXP 的典型场景(Q16)。
2. 高频易错点清单
- DROP vs TRUNCATE:DROP 连定义一起删除;TRUNCATE 只清数据、保留定义(Q28、Q150)。
- WHERE vs HAVING:WHERE 过滤行,HAVING 过滤分组/聚合结果(Q152)。
- UNION vs UNION ALL:
UNION合并多个 SELECT 结果并去重;UNION ALL保留重复行(Q151)。 - IN vs LIKE vs BETWEEN:
IN匹配集合成员,LIKE做通配符模式匹配,BETWEEN做范围匹配(Q9、Q20、Q108)。 - NULL 判断:必须用
IS NULL/IS NOT NULL,不能用= NULL或IS UNKNOWN(Q77);IFNULL()/COALESCE()用于缺省值兜底。 - TIMESTAMP vs DATETIME:两者都按无时区方式存储;区别在于 TIMESTAMP 在检索时会按会话时区换算,且取值范围更窄、字节占用更少(Q74)。需注意“TIMESTAMP 存 UTC、DATETIME 存无时区”这类表述是错误的。
- UNSIGNED:使整型列仅存非负数并把最大值翻倍(Q129)。
- LIKE 'a%':匹配以 a 开头;
%a匹配以 a 结尾;%a%匹配含 a(Q20)。 - SQL 语句以分号
;结尾(Q17);SELECT后的列清单决定返回哪些列,WHERE决定返回哪些行(Q106)。
十三、数据库设计与规范化
- 数据库设计阶段的产出是:实体清单、实体间关系、约束、数据类型与基数(cardinalities)(Q69)。
- 规范化去重的经典案例(Q97):
superheroes表中每个英雄拥有多个power1/power2/power3列,违反了第一范式。正确做法是新建“能力字典表”(code + description)与“英雄-能力”连接表(junction table),把多值属性拆分为行;而不是无限扩展power4/power5列,也不是单纯把三列压成一列(那样仍是非原子的重复组)。 - 数据冗余的合理动机:在规范化设计中适度引入冗余(如预计算缓存列)可以提高读取性能(Q56),但需自行权衡一致性维护成本。
- 临时表(Q71)的优势:会话断开即自动删除,且仅当前会话可见、无需额外管理生命周期;但它不能跨客户端共享。
结语:如何用好这份题库
这份 mysql/mysql-quiz.md 题库的价值在于覆盖面广、选项陷阱真实——许多题目专门考察易混淆概念(如 GROUP BY 与过滤、DROP 与 TRUNCATE、IN OUT 参数模式、updatable 视图属性)。建议按本文的 13 个板块分轮自测:第一轮直接答题并对照 <a href="https://link.gitcode.com/i/3dfa3dd7ac1c5e173c1f13a2e0dbb138" target="_blank">x] 答案;第二轮把答错的题整理成错题本;第三轮脱离选项,用空白页默写关键 SQL 语法(建表、JOIN、CTE、触发器、事务),再回到源码库对照 [mysql/images 中的 ER 图题复习表关系建模。搭配仓库内的德语 mysql-quiz-de.md 与乌克兰语 mysql-quiz-ua.md 版本,还可以顺便检验术语的跨语言一致性。

