mysql(ai总结每章的知识)

第二

一、本章核心能力目标(考什么?)

第2章主要考查你对 数据库和表的"定义"能力(DDL语言)。具体包括:

  1. 数据库的增删改查:创建、查看、选择、修改、删除。

  2. 数据表的增删改查:创建、查看、修改(加字段/改类型/改位置/改名/删字段)、删除。

  3. 数据类型:尤其是 DECIMAL、CHAR vs VARCHAR、DATETIME 等。

  4. 表的约束:NOT NULL、UNIQUE、PRIMARY KEY、DEFAULT、AUTO_INCREMENT。

  5. 上机实践(图书管理系统案例)对应综合应用。


二、必须默写的SQL语法(简答/填空/改错必出)

1. 数据库操作

sql

复制代码
-- 创建数据库(带字符集)
CREATE DATABASE [IF NOT EXISTS] db_name [CHARACTER SET utf8mb4];
​
-- 查看所有数据库
SHOW DATABASES;
​
-- 查看创建数据库的语句
SHOW CREATE DATABASE db_name;
​
-- 选择数据库
USE db_name;
​
-- 修改数据库字符集
ALTER DATABASE db_name CHARACTER SET gbk;
​
-- 删除数据库
DROP DATABASE [IF EXISTS] db_name;

2. 数据表操作(核心中的核心)

sql

复制代码
-- 创建表(带约束)
CREATE TABLE 表名 (
    字段1 数据类型 [约束],
    字段2 数据类型 [约束],
    ...
    [表级约束]
);
​
-- 查看所有表
SHOW TABLES;
​
-- 查看建表语句
SHOW CREATE TABLE 表名;
​
-- 查看表结构(两种等价)
DESC 表名;
DESCRIBE 表名;
​
-- 修改表名(注意:MySQL 中 RENAME TO 不需要加“TO”?PPT 中写的是 RENAME TO,实际上两种都可以,但考试以教材为准)
ALTER TABLE 旧表名 RENAME TO 新表名;
-- 或者
RENAME TABLE 旧表名 TO 新表名;
​
-- 添加字段
ALTER TABLE 表名 ADD 新字段名 数据类型 [FIRST|AFTER 字段];
​
-- 修改字段类型(MODIFY)
ALTER TABLE 表名 MODIFY 字段名 新数据类型 [位置];
​
-- 修改字段名及类型(CHANGE)
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型 [位置];
​
-- 删除字段
ALTER TABLE 表名 DROP 字段名;
​
-- 删除表
DROP TABLE [IF EXISTS] 表名;

⚠️ 易错点

  • MODIFY 只能改数据类型和位置,不能改字段名。

  • CHANGE 可以同时改字段名和类型,但必须把旧名和新名都写全。

  • 修改表名时,不要写成 RENAME TO 写成 RENAME 就错 (PPT 中用了 RENAME TO,但 MySQL 语法是 RENAME TABLE ... TO ...ALTER TABLE ... RENAME TO ...,请以教材示例为准)。


三、数据类型------考选择/判断

类型分类 具体类型 考试要点
数值 INT, DECIMAL(M,D), FLOAT, DOUBLE DECIMAL是精确小数(金融用),FLOAT/DOUBLE是近似值。
日期时间 DATE, TIME, DATETIME, TIMESTAMP DATETIME 最常用;上机实践 book 表中用了 DATETIME
字符串 CHAR(n), VARCHAR(n), TEXT CHAR定长,VARCHAR变长。CHAR效率略高,VARCHAR省空间。
二进制 BINARY, BLOB 了解即可,很少单独考。

判断题常考: ❌ "DECIMAL 是浮点数类型"------错,它是定点数。 ❌ "CHAR 和 VARCHAR 都可以存储 255 个字符且占用空间相同"------错,CHAR固定长度,VARCHAR变长。


四、约束------简答/填空/改错高频

约束 关键字 特点 删除方式
非空 NOT NULL 字段不能为 NULL ALTER TABLE ... MODIFY ... 去掉 NOT NULL
唯一 UNIQUE 值不能重复(允许 NULL) ALTER TABLE ... DROP INDEX 约束名
主键 PRIMARY KEY 唯一 + 非空,一张表只能一个 ALTER TABLE ... DROP PRIMARY KEY
默认 DEFAULT 值 未指定时自动填默认值 ALTER TABLE ... CHANGE ... 去掉 DEFAULT
自动增长 AUTO_INCREMENT 自增,必须配合主键或唯一键 修改字段去掉 AUTO_INCREMENT

联合主键写法(表级约束)

sql

复制代码
CREATE TABLE 表名 (
 id INT,
 name VARCHAR(20),
 PRIMARY KEY (id, name)   -- 两个字段共同作为主键
);

⚠️ 两个字段之间用 逗号,不是分号。

判断题常考: ✅ "PRIMARY KEY 字段不能为 NULL 也不能重复"------对。 ❌ "一个表可以有多个 PRIMARY KEY"------错,只能有一个。 ✅ "UNIQUE 约束允许 NULL 值"------对(但只能有一个 NULL,MySQL 中多个 NULL 不算重复)。


五、本章未标但可能考到的"小细节"

老师可能只标了大框架,下面这些细节也容易出选择/判断:

  1. \G 结尾符 (PPT 2.3.2 多学一招): 当字段很多时,使用 SELECT * FROM 表名\G 可以让结果纵向显示,更美观。

    可能考:下列哪个选项可以让结果纵向显示?选 \G

  2. 修改字段位置

    • FIRST:放到第一列

    • AFTER 字段名:放到某字段后面 示例:ALTER TABLE dept MODIFY deptno INT AFTER dname;

  3. AUTO_INCREMENT 初始值 : 默认从 1 开始,不是 0。

    判断题:"AUTO_INCREMENT 从 0 开始"------错。

  4. 外键约束(FOREIGN KEY): 本章只提了一句,但复习指南中未强调,可能出现在选择题。 了解:外键用于建立表之间引用关系,保证数据完整性。

  5. 删除数据表DROP TABLE IF EXISTS 表名 不会报错(如果表不存在则静默跳过)。

第六

下面我按照 必背语法 → 核心概念(含未标细节)→ 易混淆对比 → 复习策略 → 自测题 的顺序指导你。


一、本章核心能力目标(考什么?)

  1. 说出6种索引类型及各自特点(简答题高频)。

  2. 掌握三种创建索引的方式 :建表时、CREATE INDEXALTER TABLE ... ADD INDEX

  3. 掌握删除索引ALTER TABLE ... DROP INDEXDROP INDEX

  4. 理解索引的优缺点:提高查询速度,但占用空间、降低写性能。

  5. 掌握视图的创建、查看、修改、删除及通过视图操作数据(增删改查)。

  6. 能够使用 EXPLAIN 分析查询是否使用索引(选择题/判断题)。


二、必须默写的SQL语法(简答/填空/改错)

1. 创建索引的三种方式

方式一:建表时创建索引(PPT 6.1.2)

sql

复制代码
CREATE TABLE 表名 (
    字段1 数据类型 [约束],
    ...,
    {INDEX|KEY} [索引名] (字段列表),               -- 普通索引
    UNIQUE [INDEX|KEY] [索引名] (字段列表),        -- 唯一索引
    PRIMARY KEY (字段列表),                        -- 主键索引
    FULLTEXT [INDEX|KEY] [索引名] (字段列表),      -- 全文索引
    SPATIAL [INDEX|KEY] [索引名] (字段列表)        -- 空间索引
);
方式二:使用 CREATE INDEX 语句(已存在的表)

sql

复制代码
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名
ON 表名 (字段列表);
方式三:使用 ALTER TABLE 语句(已存在的表)

sql

复制代码
ALTER TABLE 表名
ADD {INDEX|KEY} [索引名] (字段列表),               -- 普通
ADD UNIQUE [INDEX|KEY] [索引名] (字段列表),        -- 唯一
ADD PRIMARY KEY (字段列表),                        -- 主键
ADD FULLTEXT [INDEX|KEY] [索引名] (字段列表),      -- 全文
ADD SPATIAL [INDEX|KEY] [索引名] (字段列表);       -- 空间

2. 删除索引的两种方式

sql

复制代码
-- 方式一
ALTER TABLE 表名 DROP INDEX 索引名;
​
-- 方式二(不能删除主键索引,主键用 ALTER TABLE ... DROP PRIMARY KEY)
DROP INDEX 索引名 ON 表名;

3. 查看索引

sql

复制代码
SHOW INDEX FROM 表名;          -- 查看所有索引信息
SHOW CREATE TABLE 表名;        -- 查看建表语句(含索引)

4. 视图操作

sql

复制代码
-- 创建视图
CREATE [OR REPLACE] VIEW 视图名 [(字段列表)] AS SELECT语句;
​
-- 查看视图定义
SHOW CREATE VIEW 视图名;
​
-- 查看视图字段
DESC 视图名;
​
-- 修改视图(两种方式)
CREATE OR REPLACE VIEW ...;   -- 替换
ALTER VIEW 视图名 ...;         -- 修改定义
​
-- 删除视图
DROP VIEW 视图名 [, 视图名2...];

5. 通过视图操作数据(与表类似)

sql

复制代码
INSERT INTO 视图名 VALUES(...);
UPDATE 视图名 SET ... WHERE ...;
DELETE FROM 视图名 WHERE ...;

注意:视图是否能成功增删改取决于视图定义(如多表视图通常不可插入/更新)。


三、6种索引类型(简答题必背清单)

根据PPT和复习指南,你需要能列出至少4种并说明特点:

索引类型 关键字 特点 允许NULL 允许重复
普通索引 INDEX / KEY 基本索引,无限制
唯一索引 UNIQUE INDEX 索引列值必须唯一 是(只能一个NULL)
主键索引 PRIMARY KEY 唯一+非空,一张表只能一个
全文索引 FULLTEXT 用于大文本字段的快速搜索
空间索引 SPATIAL 用于地理空间数据类型(如GEOMETRY)
单列/复合 (按列数分) 单列索引 vs 多个字段组成的复合索引 - -

老师可能没标但你需记

  • 复合索引遵循 最左前缀原则(查询条件必须包含索引的最左列才能有效)。

  • 创建唯一索引时,表中该列不能有重复值,否则报错。

  • 空间索引的字段必须为 NOT NULL(PPT中 address GEOMETRY NOT NULL)。


四、未标但可能考的小细节(选择题/判断题高频)

  1. 索引的缺点

    • 占用磁盘空间;

    • 降低增删改的速度(因为要维护索引);

    • 创建和维护索引耗时随数据量增加而增加。

    判断:"索引越多越好"------错。

  2. EXPLAIN 关键字

    • 用于分析 SELECT/UPDATE/DELETE/INSERT/REPLACE 是否使用索引;

    • 结果中的 key 列显示实际使用的索引,possible_keys 显示可能使用的索引。

    可能考:下列哪个语句可以查看索引是否被使用?选 EXPLAIN SELECT ...

  3. SHOW INDEX FROM 结果中的重要字段

    • Non_unique:0表示唯一索引,1表示非唯一。

    • Key_name:索引名。

    • Column_name:索引列。

    • Index_type:BTREE/HASH等。

  4. 复合索引的最左前缀原则

    • 例:INDEX (a, b, c)

    • 查询 WHERE a=1 → 使用索引;WHERE a=1 AND b=2 → 使用索引; WHERE b=2 → 不使用索引(缺少最左列a)。

    • 设计时应把最常用的字段放在最左边。

  5. 视图的 OR REPLACE

    • 如果视图已存在则替换定义,不存在则创建。

    • ALTER VIEW 功能类似,但 CREATE OR REPLACE 更常用。

  6. 通过视图更新数据的限制

    • 如果视图包含聚合函数、DISTINCTGROUP BYHAVINGUNION 或来自多表(除非使用 INSTEAD OF 触发器,但MySQL不支持),通常不能更新。

    • 考试可能考:"所有视图都可以直接通过INSERT添加数据"------错。

  7. 删除视图不影响基本表(判断题常考)。

  8. 索引的可见性 (PPT中有 Visible: YES 字段):MySQL 8.0 支持不可见索引(优化测试用),一般了解即可。


五、易混淆对比(重点记忆)

1. CREATE INDEX vs ALTER TABLE ... ADD INDEX

  • 两者功能几乎相同,但 ALTER TABLE 可以同时添加多个索引(用逗号分隔),CREATE INDEX 一次只能创建一个。

  • ALTER TABLE 还可以添加主键(ADD PRIMARY KEY),CREATE INDEX 不能。

2. DROP INDEX vs ALTER TABLE ... DROP INDEX

  • 等效,但 DROP INDEX 不能删除主键,主键需用 ALTER TABLE ... DROP PRIMARY KEY

3. 唯一索引 vs 主键索引

  • 主键索引是特殊的唯一索引,但一张表只能有一个主键,可以有多个唯一索引。

  • 主键字段不允许 NULL,唯一索引允许一个 NULL。

4. 普通索引 vs 全文索引

  • 普通索引用于精确查找或范围查找;全文索引用于 MATCH ... AGAINST 进行文本搜索。

六、本章复习策略(按优先级)

🔴 第一优先级(必须亲手敲一遍)

  • 三种创建索引的语法 (尤其是 CREATE INDEXALTER TABLE ADD INDEX)。

  • 删除索引的两种写法

  • 6种索引类型的名称和特点(能写出至少4种)。

  • 视图的创建和查看CREATE VIEW ... AS SELECT)。

🟠 第二优先级(理解并记住易错点)

  • 最左前缀原则(选择题)。

  • EXPLAIN 的作用和关键列(key)。

  • 通过视图操作数据的限制。

  • 索引的优缺点。

🟡 第三优先级(浏览,防止冷门)

  • 空间索引(了解需要 GEOMETRY 类型,且 NOT NULL)。

  • SHOW INDEX FROM 各字段含义(Non_uniqueCollation 等)。

  • 视图的 ALTER VIEW 语法。


七、自测题(检验掌握程度)

单选题

  1. 下列哪种索引要求字段值不能重复且不能为NULL? A. UNIQUE INDEX B. PRIMARY KEY C. INDEX D. FULLTEXT 答案:B

  2. 在已有表 studentname 列上创建普通索引 idx_name,正确的语句是: A. CREATE INDEX idx_name ON student(name); B. CREATE INDEX idx_name student(name); C. ALTER TABLE student ADD INDEX idx_name(name); D. A和C都正确 答案:D

  3. 关于复合索引 INDEX (a, b, c),以下哪个查询不能 使用该索引? A. WHERE a = 1 B. WHERE a = 1 AND c = 3 C. WHERE b = 2 AND a = 1 D. WHERE b = 2 答案:D(缺少最左列a)

判断题

  1. ( )创建唯一索引时,如果表中已有重复数据,仍可成功创建。 (会报错,需先清理重复数据)。

  2. ( )视图是虚拟表,删除视图会同时删除基本表中的数据。 (只删除视图定义,不影响基本表)。

  3. ( )使用 EXPLAIN SELECT ... 可以查看MySQL是否使用了索引。

简答题(模拟考试)

  1. 请列出MySQL中至少4种索引类型,并说明每种索引的特点。 (参考上面的表格,写出普通、唯一、主键、全文即可)

  2. 请写出在已有表 empenamedeptno 字段上创建复合唯一索引 uniq_ename_dept 的两种SQL语句。

    sql

    复制代码
    -- 方式1
    CREATE UNIQUE INDEX uniq_ename_dept ON emp(ename, deptno);
    -- 方式2
    ALTER TABLE emp ADD UNIQUE INDEX uniq_ename_dept(ename, deptno);

第四

一、本章核心能力目标(考什么?)

  1. 熟记 SELECT 语句的完整语法顺序(FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT),顺序写错即错。

  2. 掌握 DISTINCT 去重:作用在多个字段时,组合去重。

  3. 掌握条件查询 :比较运算符(=, <>, <, >, >=, <=)、INIS NULLLIKE%_ 通配符及转义)。

  4. 掌握逻辑运算符AND, OR, NOT,以及 AND 优先级高于 OR

  5. 掌握聚合函数COUNT, SUM, AVG, MAX, MIN,特别注意 COUNT(*)COUNT(字段) 的区别(后者忽略 NULL)。

  6. 掌握分组查询GROUP BY + 聚合函数,以及 HAVING 对分组后结果过滤(HAVING 可以使用聚合函数,WHERE 不能)。

  7. 掌握排序ORDER BY 默认 ASC,多个字段排序规则,NULL 视为最小值。

  8. 掌握限量查询LIMIT [偏移量,] 记录数,偏移量从 0 开始。

  9. 了解常用内置函数CONCAT, IF, IFNULL 等(选择题可能出现)。

  10. 掌握别名 :表别名和字段别名的 AS 可省略。


二、必须默写的 SELECT 语法结构(填空/改错高频)

sql

复制代码
SELECT [DISTINCT] 字段1 [AS 别名1], 字段2 [AS 别名2], 聚合函数(...)
FROM 表名 [AS 表别名]
[WHERE 条件表达式]               -- 分组前过滤,不能使用聚合函数
[GROUP BY 分组字段1, 分组字段2]
[HAVING 分组后过滤条件]          -- 可以使用聚合函数
[ORDER BY 排序字段1 [ASC|DESC], 排序字段2 [ASC|DESC]]
[LIMIT [偏移量,] 记录数];

⚠️ 重要 :各个子句的顺序绝对不能错 。例如 WHERE 必须在 GROUP BY 之前,ORDER BY 必须在 LIMIT 之前。


三、老师可能没标但你需掌握的细节(选择题/判断题高频)

1. DISTINCT 作用于多个字段

  • SELECT DISTINCT 字段1, 字段2 FROM ...:只有字段1和字段2的值都相同才被去重。

  • 判断:"DISTINCT 只能作用于一个字段" ------

2. 比较运算符与 NULL

  • 任何与 NULL 的比较(= NULL, <> NULL)结果都是 NULL(未知),不会返回任何行。

  • 判断 NULL 必须使用 IS NULLIS NOT NULL

  • 示例:SELECT * FROM emp WHERE comm = NULL; 结果为空(错误写法)。

3. LIKE 的通配符及转义

  • % 匹配任意长度(包括0个)字符;_ 匹配单个字符。

  • 如果要查询的字符串本身包含 %_,需要用 \ 转义,例如 '%\%%' 表示包含 % 的字符串。

  • 示例:WHERE ename LIKE '%\%%' 查询姓名中含有 % 的员工。

4. ANDOR 的优先级

  • AND 优先级高于 OR 。如果不加括号,会先计算 AND 两侧的条件。

  • 示例:WHERE ename='刘一' OR ename='李四' AND deptno=30 实际等价于 ename='刘一' OR (ename='李四' AND deptno=30),与直觉可能不同。

  • 建议:混合使用时加括号明确逻辑。

5. BETWEEN ... AND ... 包含边界

  • WHERE sal BETWEEN 2000 AND 3000 等价于 sal >= 2000 AND sal <= 3000,包含两端。

  • NOT BETWEEN 则排除边界。

6. 聚合函数的注意事项

  • COUNT(*) 统计所有行(包括 NULL);COUNT(字段) 统计该字段非 NULL 的行数。

  • AVG() 自动忽略 NULL 值,若希望将 NULL 当作 0 计算,需先用 IFNULL(字段,0) 转换。

  • 聚合函数不能直接出现在 WHERE 子句中 。例如 WHERE AVG(sal) > 3000 是错误的。

  • 需要过滤聚合结果时,必须使用 HAVING

7. GROUP BY 的常见陷阱

  • 如果 SELECT 中出现了非分组字段(且没有聚合函数),MySQL 在某些模式下会报错或返回不确定值。考试可能考:"SELECT 的字段必须全部包含在 GROUP BY 中或使用聚合函数" ------ (严格 SQL 模式)。

  • 分组后查询的字段通常是分组字段 + 聚合函数

8. HAVING vs WHERE

  • WHERE 在分组过滤行,不能使用聚合函数。

  • HAVING 在分组过滤组,可以使用聚合函数。

  • 示例:SELECT deptno, AVG(sal) FROM emp GROUP BY deptno HAVING AVG(sal) > 3000;

9. ORDER BY 细节

  • 默认升序(ASC),降序用 DESC

  • 可以对多个字段排序:ORDER BY job ASC, empno DESC

  • NULL 在排序中视为最小值(升序时排在最前,降序时排在最后)。

  • 判断:"ORDER BY 只能按一个字段排序" ------

10. LIMIT 的两种用法

  • LIMIT 5:返回前 5 行(等价于 LIMIT 0,5)。

  • LIMIT 3,5:从第 4 行开始(偏移量 0 表示第一行),返回 5 行。

  • 注意:偏移量从 0 开始,不是 1。

  • 示例:查询工资第 2~5 名:ORDER BY sal DESC LIMIT 1,4

11. 常用内置函数(可能考选择题)

  • CONCAT(str1, str2, ...):连接字符串。

  • IF(expr, true_value, false_value):条件判断。

  • IFNULL(expr, default_value):若 expr 为 NULL 则返回默认值。

  • 例如:SELECT IFNULL(comm, 0) FROM emp;

12. 别名(AS 可省略)

  • 表别名:FROM emp e 等价于 FROM emp AS e

  • 字段别名:SELECT ename AS name 等价于 SELECT ename name

  • 注意:别名中如果包含空格或特殊字符,需要用单引号或反引号括起来。


四、易混淆对比(重点记忆)

对比项 说明 示例
COUNT(*) vs COUNT(字段) * 包含 NULL 行;字段 忽略 NULL COUNT(comm) 只统计非 NULL 奖金
WHERE vs HAVING WHERE 过滤行(分组前);HAVING 过滤组(分组后) WHERE sal>1000HAVING AVG(sal)>2000
AND vs OR 优先级 AND 先于 OR 计算 见上文
BETWEEN vs 连续 AND 效果相同,BETWEEN 更简洁 sal BETWEEN 2000 AND 3000
LIKE '%' vs = = 精确匹配,LIKE 可带通配符 ename='张三'ename LIKE '张%'
LIMIT 偏移量 第 1 条记录偏移 0,第 2 条偏移 1 LIMIT 2,3 返回第 3,4,5 条

五、上机实践指导(紧扣期末可能题型)

PPT 4.6 节的图书管理系统案例非常典型,覆盖了 WHEREORDER BYLIMITLIKEINBETWEEN 等。建议你亲手敲一遍下面几个核心查询:

sql

复制代码
-- 1. 查询可借阅图书(state=0)的名称和上架时间
SELECT name, upload_time FROM book WHERE state = 0;
​
-- 2. 按名称升序排序,取前5条的名称、价格、状态
SELECT name, price, state FROM book ORDER BY name ASC LIMIT 5;
​
-- 3. 价格大于50的图书名称和价格
SELECT name, price FROM book WHERE price > 50;
​
-- 4. 价格在30到50之间的图书(包含边界)
SELECT name, price FROM book WHERE price BETWEEN 30 AND 50;
​
-- 5. 已借阅图书(state=1)的名称、借阅人编号、借阅时间
SELECT name, borrower_id, borrow_time FROM book WHERE state = 1;
​
-- 6. 名称包含“Java”的图书名称
SELECT name FROM book WHERE name LIKE '%Java%';
​
-- 7. 名称以“入门”结尾的图书名称
SELECT name FROM book WHERE name LIKE '%入门';
​
-- 8. 名称为“西游记”或“红楼梦”的图书名称和价格
SELECT name, price FROM book WHERE name IN('西游记','红楼梦');

老师可能不标但你需注意

  • 第4个查询中 BETWEEN 30 AND 50 包含边界值。

  • 第6、7个查询中 % 的位置不同,含义不同(包含 vs 结尾)。

  • 第8个查询中 IN 等价于多个 OR 条件。


六、自测题(检验掌握程度)

单选题

  1. 下列哪个子句必须出现在 GROUP BY 之后? A. WHERE B. HAVING C. ORDER BY D. LIMIT 答案:BHAVING 只能跟在 GROUP BY 后面)

  2. 查询员工表中平均工资大于3000的部门,正确的语句是: A. SELECT deptno, AVG(sal) FROM emp WHERE AVG(sal)>3000 GROUP BY deptno; B. SELECT deptno, AVG(sal) FROM emp GROUP BY deptno HAVING AVG(sal)>3000; C. SELECT deptno, AVG(sal) FROM emp HAVING AVG(sal)>3000 GROUP BY deptno; D. SELECT deptno, AVG(sal) FROM emp GROUP BY deptno WHERE AVG(sal)>3000; 答案:B

  3. 关于 LIMIT 3,5 的说法正确的是: A. 返回第3到第5条记录 B. 返回前3条记录 C. 返回从第4条开始的5条记录 D. 返回第3条后的5条记录 答案:C

  4. 查询姓名以"张"开头且名字长度为2个字的员工(假设中文字符占一个字符),应使用: A. WHERE ename LIKE '张_' B. WHERE ename LIKE '张%' C. WHERE ename = '张_' D. WHERE ename LIKE '张__' 答案:A_ 匹配单个字符)

  5. 关于 COUNT(*)COUNT(comm) 的区别,说法正确的是: A. 两者结果完全相同 B. COUNT(comm) 统计包括 NULL 的行数 C. COUNT(*) 统计所有行,COUNT(comm) 忽略 comm 为 NULL 的行 D. COUNT(*)COUNT(comm)答案:C

判断题

  1. ( )WHERE 子句中可以使用 SUM() 函数进行条件过滤。 (聚合函数不能直接用在 WHERE 中)

  2. ( )ORDER BY 默认按升序排序,NULL 值在升序中排在最后。 NULL 被视为最小值,排在升序的最前面)

  3. ( )SELECT DISTINCT ename, job 表示查询结果中 ename 唯一,job 可以重复。 (两个字段的组合值唯一才去重)

  4. ( )LIMIT 0,10LIMIT 10 返回的结果相同。 (偏移量0可省略)

  5. ( )SELECT ename, sal FROM emp ORDER BY sal; 默认按 sal 降序排列。 (默认升序 ASC)

简答题(模拟考试)

  1. 请写出 SELECT 语句中各子句(FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT)的正确顺序,并简述 WHERE 和 HAVING 的区别。 参考答案 : 顺序:FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT。 区别:WHERE 在分组前对行进行过滤,不能使用聚合函数;HAVING 在分组后对组进行过滤,可以使用聚合函数。

  2. 写出查询员工表 emp 中,平均工资低于2500的部门编号及其平均工资的 SQL 语句。

    sql

    复制代码
    SELECT deptno, AVG(sal) AS avg_sal
    FROM emp
    GROUP BY deptno
    HAVING AVG(sal) < 2500;

    第五

    一、本章核心能力目标(考什么?)

    1. 理解交叉连接(笛卡尔积) 及其产生的结果行数(表1行数 × 表2行数)。

    2. 掌握内连接[INNER] JOIN ... ON,只返回匹配的记录。

    3. 掌握外连接LEFT JOIN(左表全保留)和 RIGHT JOIN(右表全保留)。

    4. 掌握自连接:同一张表通过别名连接,常用于查询"同部门员工"等。

    5. 掌握子查询的四种用法INEXISTSANY/SOMEALL,以及与比较运算符结合的子查询。

    6. 理解外键约束 :添加、删除,以及级联操作(ON DELETE CASCADE 等)。

    7. 掌握关联表的插入/删除顺序:先主表后从表(插入),先删从表再删主表(删除)。


    二、必须默写的核心语法

    1. 交叉连接(笛卡尔积)

    sql

    复制代码
    SELECT * FROM 表1 CROSS JOIN 表2;
    -- 等价于
    SELECT * FROM 表1, 表2;

    注意 :如果没有 WHERE 条件,返回的就是两表行数的乘积,通常是无意义的。

    2. 内连接

    sql

    复制代码
    SELECT 字段
    FROM 表1 [INNER] JOIN 表2 ON 表1.关联字段 = 表2.关联字段;
    • INNER 可省略。

    • 也可以使用 WHERE 条件实现内连接(老式写法):FROM 表1, 表2 WHERE 条件,但推荐使用 JOIN ... ON

    3. 外连接(左/右)

    sql

    复制代码
    -- 左连接:左表所有行 + 右表匹配的行
    SELECT 字段 FROM 左表 LEFT JOIN 右表 ON 条件;
    
    -- 右连接:右表所有行 + 左表匹配的行
    SELECT 字段 FROM 左表 RIGHT JOIN 右表 ON 条件;

    4. 自连接(内连接的一种特殊形式)

    sql

    复制代码
    SELECT e1.*
    FROM emp e1
    JOIN emp e2 ON e1.deptno = e2.deptno
    WHERE e2.ename = '王五';

    5. 子查询

    5.1 IN / NOT IN

    sql

    复制代码
    SELECT * FROM dept WHERE deptno IN (SELECT deptno FROM emp WHERE sal > 2900);
    5.2 EXISTS / NOT EXISTS

    sql

    复制代码
    SELECT * FROM dept WHERE EXISTS 
      (SELECT 1 FROM emp WHERE emp.deptno = dept.deptno AND emp.sal > 2900);
    • EXISTS 只关心子查询是否有行返回,不关心具体值。

    • 外层查询的每一行都会执行子查询(关联子查询)。

    5.3 ANY (或 SOME)

    sql

    复制代码
    SELECT * FROM emp WHERE deptno=10 AND sal > ANY(SELECT sal FROM emp WHERE deptno=20);
    • > ANY 表示大于子查询中的最小值
    5.4 ALL

    sql

    复制代码
    SELECT * FROM emp WHERE deptno=10 AND sal > ALL(SELECT sal FROM emp WHERE deptno=20);
    • > ALL 表示大于子查询中的最大值
    5.5 比较运算符直接使用子查询(子查询返回单值)

    sql

    复制代码
    SELECT * FROM emp WHERE job = (SELECT job FROM emp WHERE ename = '王五');

    6. 外键约束

    添加外键

    sql

    复制代码
    ALTER TABLE 从表 
    ADD CONSTRAINT 外键名 
    FOREIGN KEY (外键字段) REFERENCES 主表(主键字段)
    [ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
    [ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}];
    删除外键

    sql

    复制代码
    ALTER TABLE 从表 DROP FOREIGN KEY 外键名;

    三、老师可能没标但你需掌握的细节(选择题/判断题高频)

    1. 交叉连接(笛卡尔积)的实用性

    • 交叉连接如果不加过滤条件,结果数 = 表1行数 × 表2行数。实际业务中很少直接使用,但它是内连接/外连接的基础。

    • 判断:"交叉连接返回的是两表中匹配的记录" ------ ,它返回所有组合。

    2. 内连接与 WHERE 多表等价性

    • FROM A JOIN B ON A.id = B.idFROM A, B WHERE A.id = B.id 在功能上等价,但推荐使用 JOIN 语法,更清晰。

    3. 自连接必须使用别名

    • 同一张表在 FROM 中出现两次,必须给至少一个表起别名,否则会报错。

    • 示例:SELECT * FROM emp e1, emp e2 WHERE e1.deptno = e2.deptno

    4. 左/右连接中,ON 条件与 WHERE 条件的区别

    • ON 决定如何匹配两表;WHERE 对连接后的结果进行过滤。

    • 外连接中,ON 条件不会过滤左表(或右表)的全部记录,但 WHERE 可能会把左表中不满足条件的行也过滤掉。

    • 易错点:想要保留左表所有记录,过滤条件应放在 ON 中,而不是 WHERE

    5. 子查询的两种类型

    • 不相关子查询 :子查询可以独立运行,例如 SELECT deptno FROM emp WHERE sal>2900

    • 相关子查询 :子查询中使用了外层查询的字段,例如 EXISTS 子查询中的 emp.deptno = dept.deptno。相关子查询对外层每一行都执行一次。

    6. INEXISTS 的性能选择(考试可能考判断)

    • 外表大、内表小 时,适合用 IN(因为 IN 先执行子查询,生成结果集后再匹配)。

    • 外表小、内表大 时,适合用 EXISTS(因为 EXISTS 对外表每一行执行子查询,可以利用内表索引)。

    • 判断:"IN 子查询总是比 EXISTS 快" ------ ,取决于数据分布。

    7. ANYALL 的等价写法

    • > ANY (子查询) 等价于 > MIN(子查询)

    • < ANY 等价于 < MAX(子查询)

    • > ALL 等价于 > MAX(子查询)

    • < ALL 等价于 < MIN(子查询)

    • 常考:查询工资高于部门20中任意一个人的工资 → 使用 > ANY> MIN

    8. 子查询返回空值时的行为

    • NOT IN (空集) 会返回 FALSE?实际:如果子查询结果中包含 NULLNOT IN 会返回空(因为 NULL 比较的结果为 UNKNOWN)。所以使用 NOT IN 时要确保子查询结果不含 NULL,否则可能得不到预期结果。

    • 安全做法:在子查询中使用 WHERE 字段 IS NOT NULL,或改用 NOT EXISTS

    9. 外键约束的存储引擎要求

    • MySQL 中只有 InnoDB 引擎支持外键约束。MyISAM 不支持。

    • 判断:"所有存储引擎都支持外键" ------

    10. 外键约束的级联操作

    • ON DELETE CASCADE:删除主表记录时,自动删除从表中引用该记录的行。

    • ON DELETE SET NULL:删除主表记录时,将从表的外键列设为 NULL(要求该列允许 NULL)。

    • ON DELETE RESTRICT / NO ACTION:如果从表有引用,则阻止删除主表记录(默认行为)。

    • 考试可能考:哪种级联操作可以避免"垃圾数据"? CASCADESET NULL

    11. 关联表数据操作的顺序

    • 插入:先插入主表(有主键),再插入从表(外键值必须存在于主表)。

    • 删除:先删除从表中引用的行,再删除主表的行。否则会违反外键约束。

    • 更新主键:如果从表引用了该主键,直接更新会失败,需要级联或先修改从表。

    12. 外键名的引号问题

    • 定义外键名称时不能加引号:CONSTRAINT fk_name(正确),CONSTRAINT 'fk_name'(错误)。

    四、易混淆对比(重点记忆)

    对比项 说明 示例
    内连接 vs 外连接 内连接只返回匹配行;外连接返回一侧全部行 LEFT JOIN 保留左表所有行
    左连接 vs 右连接 左连接保留左表,右连接保留右表;两者可互换 A LEFT JOIN B 等价于 B RIGHT JOIN A
    IN vs EXISTS IN 适合内表小;EXISTS 适合外表小;EXISTS 可处理 NULL 见上
    ANY vs ALL > ANY:大于最小值;> ALL:大于最大值 > ANY(...) 等价于 > MIN(...)
    子查询返回单值 vs 多值 单值可用 =,多值必须用 IN/ANY/ALL job = (子查询) 子查询必须返回一行一列
    删除外键 vs 删除索引 外键需用 DROP FOREIGN KEY,普通索引用 DROP INDEX ALTER TABLE t DROP FOREIGN KEY fk_name
    ON DELETE CASCADE vs SET NULL CASCADE 删除从表行;SET NULL 仅将外键设为 NULL -

    五、上机实践要点(紧扣期末)

    PPT 5.4 节图书管理系统案例覆盖了:

    • 多表连接(查询张三借阅的图书)。

    • 子查询(比《西游记》价格高、高于平均价、与《三国演义》状态相同)。

    • ANY/ALL 子查询(已借阅 vs 未借阅的价格比较)。

    • 添加外键(book.borrower_id 引用 user.id)。

    建议手动敲一遍以下核心查询:

    sql

    复制代码
    -- 1. 内连接:查询所有员工及其部门名称(已分配部门的)
    SELECT e.ename, d.dname FROM emp e JOIN dept d ON e.deptno = d.deptno;
    
    -- 2. 左连接:查询所有部门及其员工姓名(没有员工的部门也显示)
    SELECT d.dname, e.ename FROM dept d LEFT JOIN emp e ON e.deptno = d.deptno;
    
    -- 3. 自连接:查询与“张三”同部门的员工
    SELECT e2.* FROM emp e1 JOIN emp e2 ON e1.deptno = e2.deptno WHERE e1.ename = '张三';
    
    -- 4. 子查询 IN:查询有工资>2900的部门信息
    SELECT * FROM dept WHERE deptno IN (SELECT deptno FROM emp WHERE sal > 2900);
    
    -- 5. 子查询 EXISTS:同上
    SELECT * FROM dept d WHERE EXISTS (SELECT 1 FROM emp e WHERE e.deptno = d.deptno AND e.sal > 2900);
    
    -- 6. ANY 子查询:查询部门10中工资高于部门20任意一人的员工
    SELECT * FROM emp WHERE deptno=10 AND sal > ANY(SELECT sal FROM emp WHERE deptno=20);
    
    -- 7. ALL 子查询:查询部门10中工资高于部门20所有人的员工
    SELECT * FROM emp WHERE deptno=10 AND sal > ALL(SELECT sal FROM emp WHERE deptno=20);
    
    -- 8. 添加外键
    ALTER TABLE book ADD CONSTRAINT FK_borrower FOREIGN KEY (borrower_id) REFERENCES user(id);

    六、自测题(检验掌握程度)

    单选题

    1. 下列哪种连接会返回左表的所有记录,即使右表中没有匹配? A. INNER JOIN B. LEFT JOIN C. CROSS JOIN D. RIGHT JOIN 答案:B

    2. 查询与"张三"同部门的员工信息,应使用的连接方式是: A. 左连接 B. 右连接 C. 内连接 + 自连接 D. 交叉连接 答案:C(自连接是内连接的一种)

    3. 子查询 SELECT * FROM dept WHERE deptno IN (SELECT deptno FROM emp WHERE sal>3000) 中,外层查询的 deptno 与子查询的 deptno 的关系是: A. 不相干 B. 相关子查询 C. 同一张表 D. 没有关系 答案:A(这里子查询不依赖外层,是不相关子查询)

    4. 以下哪个关键字必须与比较运算符一起使用? A. IN B. EXISTS C. ANY D. NOT 答案:CANY/ALL 必须与 >, <, = 等连用)

    5. 在 MySQL 中,以下哪个存储引擎支持外键约束? A. MyISAM B. MEMORY C. InnoDB D. ARCHIVE 答案:C

    判断题

    1. ( )FROM A, B WHERE A.id = B.idFROM A JOIN B ON A.id = B.id 的效果完全相同。 (都是内连接)

    2. ( )执行 DELETE FROM dept WHERE deptno=10 时,如果员工表中有 deptno=10 的员工且外键约束为默认的 RESTRICT,则会自动删除这些员工。 (会阻止删除,需要先处理从表)

    3. ( )EXISTS 子查询中的 SELECT * 可以改为 SELECT 1SELECT NULL,结果不变。 EXISTS 只检查结果集是否为空,不关心具体值)

    4. ( )使用 NOT IN (子查询) 时,如果子查询结果中包含 NULL,则整个查询可能返回空结果。 (因为 NOT IN (NULL, ...) 的逻辑结果是 UNKNOWN

    5. ( )左连接查询的结果集行数一定大于等于内连接查询的结果集行数。 (左连接至少保留左表所有行,内连接只保留匹配行)

    简答题(模拟考试)

    1. 请简述内连接、左外连接、右外连接的区别,并写出左连接的语法。 参考答案

      • 内连接:只返回两表中连接条件匹配的行。

      • 左外连接:返回左表所有行,右表不匹配的填 NULL

      • 右外连接:返回右表所有行,左表不匹配的填 NULL。 左连接语法:SELECT ... FROM 表1 LEFT JOIN 表2 ON 条件;

    2. 写出查询"部门平均工资大于3000的部门名称和平均工资"的 SQL 语句,要求使用子查询或连接查询任一方式。

      sql

      复制代码
      -- 方法1:连接 + 分组
      SELECT d.dname, AVG(e.sal) AS avg_sal
      FROM dept d JOIN emp e ON d.deptno = e.deptno
      GROUP BY d.deptno, d.dname
      HAVING AVG(e.sal) > 3000;
      ​
      -- 方法2:子查询(先查出符合条件的部门编号)
      SELECT dname, (SELECT AVG(sal) FROM emp WHERE deptno = d.deptno) AS avg_sal
      FROM dept d
      WHERE d.deptno IN (SELECT deptno FROM emp GROUP BY deptno HAVING AVG(sal) > 3000);

第八

一、本章核心能力目标(考什么?)

  1. 存储过程 :创建(CREATE PROCEDURE)、调用(CALL)、查看(SHOW PROCEDURE STATUS)、修改(ALTER)、删除(DROP PROCEDURE)。重点掌握 IN / OUT / INOUT 参数。

  2. 存储函数 :创建(CREATE FUNCTION)、调用(SELECT)、删除(DROP FUNCTION)。重点掌握 RETURNSRETURN

  3. 变量 :系统变量(全局/会话)、用户变量(@var)、局部变量(DECLARE)。作用域和赋值方式。

  4. 流程控制IFCASELOOPREPEATWHILELEAVEITERATE

  5. 错误处理DECLARE ... HANDLERCONTINUE / EXIT)。

  6. 游标:声明、打开、获取、关闭,与错误处理配合遍历结果集。

  7. 触发器 :创建(CREATE TRIGGER)、触发时机(BEFORE/AFTER)、触发事件(INSERT/UPDATE/DELETE)、NEW / OLD、删除(DROP TRIGGER)。


二、必须默写的核心语法

1. 存储过程

sql

复制代码
-- 创建
DELIMITER //
CREATE PROCEDURE 过程名 ([IN|OUT|INOUT 参数名 类型])
[特征...]
BEGIN
    -- SQL语句
END //
DELIMITER ;

-- 调用
CALL 过程名(参数值, @输出变量);

-- 查看状态
SHOW PROCEDURE STATUS LIKE '过程名';

-- 查看创建语句
SHOW CREATE PROCEDURE 过程名;

-- 删除
DROP PROCEDURE [IF EXISTS] 过程名;

2. 存储函数

sql

复制代码
-- 创建
DELIMITER //
CREATE FUNCTION 函数名(参数名 类型)
RETURNS 返回类型
[特征...]
BEGIN
    RETURN (SELECT ...);
END //
DELIMITER ;

-- 调用
SELECT 函数名(参数值);

-- 删除
DROP FUNCTION [IF EXISTS] 函数名;

3. 变量

sql

复制代码
-- 用户变量(以@开头,会话级)
SET @var = 10;
SELECT @var := 列名 FROM ...;
SELECT 列名 INTO @var FROM ...;

-- 局部变量(必须在 BEGIN...END 中,且必须在游标和错误处理程序之前声明)
DECLARE var_name 类型 [DEFAULT 默认值];

4. 流程控制

sql

复制代码
-- IF
IF 条件 THEN
    ...
ELSEIF 条件 THEN
    ...
ELSE
    ...
END IF;

-- CASE(两种形式)
CASE 表达式
    WHEN 值1 THEN ...
    WHEN 值2 THEN ...
    ELSE ...
END CASE;

CASE
    WHEN 条件1 THEN ...
    WHEN 条件2 THEN ...
    ELSE ...
END CASE;

-- LOOP(需配合 LEAVE 退出)
[标签:] LOOP
    IF 条件 THEN LEAVE 标签; END IF;
END LOOP 标签;

-- REPEAT(至少执行一次,条件为真退出)
[标签:] REPEAT
    ...
    UNTIL 条件
END REPEAT 标签;

-- WHILE(条件为假时进入循环?注意:WHILE 条件为真时执行)
[标签:] WHILE 条件 DO
    ...
END WHILE 标签;

-- 跳转
LEAVE 标签;   -- 退出整个循环
ITERATE 标签; -- 跳过本次循环剩余语句,开始下一次循环

5. 错误处理

sql

复制代码
-- 自定义错误名称
DECLARE 错误名称 CONDITION FOR SQLSTATE '23000';  -- 或 1062

-- 错误处理程序
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET mark = 1;
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ... END;

6. 游标

sql

复制代码
-- 声明游标(必须在局部变量之后,错误处理程序之前)
DECLARE 游标名 CURSOR FOR SELECT ...;

-- 打开
OPEN 游标名;

-- 获取一行
FETCH 游标名 INTO 变量1, 变量2, ...;

-- 关闭
CLOSE 游标名;

7. 触发器

sql

复制代码
-- 创建
CREATE TRIGGER 触发器名
{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名
FOR EACH ROW
BEGIN
    -- 可使用 NEW.列名(INSERT/UPDATE时新值)和 OLD.列名(UPDATE/DELETE时旧值)
END;

-- 查看
SHOW TRIGGERS;
SELECT * FROM information_schema.triggers WHERE trigger_name = '...';

-- 删除
DROP TRIGGER [IF EXISTS] [数据库名.]触发器名;

三、老师可能没标但你需掌握的细节(选择题/判断题高频)

1. 存储过程的参数模式

  • IN:输入参数,调用时传入值(可以是常量或变量),过程内部可修改但不返回。

  • OUT:输出参数,过程内部修改后返回给调用者(初始值为 NULL)。

  • INOUT:输入输出参数,既传入值,又可修改后返回。

  • 调用时,对于 OUTINOUT,必须使用变量 (如 @var)接收返回值。

2. 存储函数与存储过程的区别(简答高频)

  • 存储过程没有返回值 (或者说通过 OUT 参数返回多个值),存储函数必须返回一个值 (通过 RETURN)。

  • 存储过程用 CALL 调用,存储函数用 SELECT 调用(就像内置函数)。

  • 存储函数可以在 SQL 表达式中使用(如 SELECT func(col) FROM ...),存储过程不能。

3. DELIMITER 的作用

  • 默认 ; 结束语句,但在存储过程/函数体中可能包含多条语句,需要临时改变分隔符,以便整个过程被当成一个语句提交。常用 DELIMITER // 然后以 // 结尾,最后恢复 DELIMITER ;

  • 判断:"创建存储过程时,必须使用 DELIMITER 命令"------(在命令行或某些工具中可能需要,但在某些图形界面中可省略,但考试常考其作用)。

4. 变量的作用域

  • 系统变量GLOBAL 影响整个服务器,SESSION 影响当前连接。修改全局变量后新连接生效,当前已连接的会话不受影响(除非再修改会话变量)。

  • 用户变量 :以 @ 开头,会话级,可以在任何地方使用(甚至跨存储过程)。

  • 局部变量 :用 DECLARE 声明,仅在 BEGIN...END 块内有效,且必须在块的开头(变量声明必须在游标、条件、处理程序之前)。局部变量不需要 @

5. DECLARE 的顺序要求

BEGIN...END 块中,声明顺序必须为:

  1. 局部变量 (DECLARE var...)

  2. 条件 (DECLARE CONDITION...) 和 游标 (DECLARE CURSOR...)

  3. 错误处理程序 (DECLARE HANDLER...) 顺序错了会报语法错误。可能考判断:"在存储过程中,可以先把游标声明放在变量声明前面"------

6. 游标遍历时判断结束

  • 常用 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;02000 表示 NOT FOUND)。

  • FETCH 后判断 done 变量,若为1则退出循环。

7. 触发器中的 NEWOLD

  • INSERT 操作:只有 NEW(新插入的行),没有 OLD

  • DELETE 操作:只有 OLD(被删除的行),没有 NEW

  • UPDATE 操作:NEW 表示更新后的行,OLD 表示更新前的行。

  • 可以在 BEFORE 触发器中修改 NEW 列的值(如 SET NEW.column = ...),AFTER 触发器中不能修改。

8. 触发器的触发时机

  • BEFORE:在 INSERT/UPDATE/DELETE 操作之前执行,可用于数据验证或修改。

  • AFTER:在操作之后执行,一般用于日志记录、级联更新等。

  • 判断:"触发器可以在 INSERT 操作之前和之后都触发"------(可以创建多个触发器,但同一表同一时机同一事件只能一个?MySQL 5.7.2+ 允许同一事件有多个触发器,但考试通常认为一个表对同一事件只能有一个触发器,具体看教材)。

9. LEAVEITERATE 的区别

  • LEAVE 相当于 break:完全退出循环。

  • ITERATE 相当于 continue:跳过本次循环剩余语句,进入下一次循环。

10. 自定义错误处理

  • CONTINUE:发生错误后继续执行后续语句(如设置一个标记)。

  • EXIT:发生错误后立即退出当前 BEGIN...END 块。

  • 可以用来捕获重复键、没有数据等错误,避免存储过程崩溃。


四、易混淆对比(重点记忆)

对比项 说明
存储过程 vs 存储函数 过程无返回值(或用OUT),函数必须有RETURN;调用方式不同
IN vs OUT vs INOUT IN:只进不出;OUT:只出不进(初始NULL);INOUT:可进可出
局部变量 vs 用户变量 局部用DECLARE,无@,作用域在块内;用户变量以@开头,会话级
REPEAT vs WHILE REPEAT至少执行一次(先执行后判断);WHILE先判断后执行(可能0次)
LEAVE vs ITERATE LEAVE退出循环;ITERATE跳至下一次循环
BEFORE vs AFTER 触发器 BEFORE可在修改前校验/修改NEW;AFTER用于操作后记录
NEW vs OLD INSERT有NEW无OLD;DELETE有OLD无NEW;UPDATE两者都有
SHOW PROCEDURE STATUS vs SHOW CREATE PROCEDURE 前者显示状态信息,后者显示创建语句

五、上机实践要点(紧扣期末)

PPT 8.8 节图书管理系统案例覆盖了:

  • 存储过程 proc_1:带连接查询和条件判断(IF)。

  • 存储过程 proc_2:简单查询。

  • 存储函数 func_1:带参数的返回值。

  • 存储函数 func_2:带 IF 和局部变量。

  • 触发器 trig_bookAFTER INSERT 更新另一张表。 建议手动敲一遍以下核心示例:

sql

复制代码
-- 1. 存储过程(IN参数)
DELIMITER //
CREATE PROCEDURE GetEmpBySal(IN min_sal DECIMAL(7,2))
BEGIN
    SELECT * FROM emp WHERE sal > min_sal;
END //
DELIMITER ;
CALL GetEmpBySal(3000);

-- 2. 存储函数(RETURNS)
DELIMITER //
CREATE FUNCTION GetDeptName(emp_no INT) RETURNS VARCHAR(20)
BEGIN
    RETURN (SELECT dname FROM dept d JOIN emp e ON d.deptno = e.deptno WHERE e.empno = emp_no);
END //
DELIMITER ;
SELECT GetDeptName(9839);

-- 3. 触发器(AFTER DELETE)
CREATE TRIGGER backup_del_emp
AFTER DELETE ON emp FOR EACH ROW
INSERT INTO emp_backup VALUES (OLD.empno, OLD.ename, OLD.job, ...);

-- 4. 游标示例(遍历)
DELIMITER //
CREATE PROCEDURE cursor_demo()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE v_ename VARCHAR(20);
    DECLARE cur CURSOR FOR SELECT ename FROM emp;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO v_ename;
        IF done THEN LEAVE read_loop; END IF;
        -- 处理逻辑
    END LOOP;
    CLOSE cur;
END //
DELIMITER ;

六、自测题(检验掌握程度)

单选题

  1. 下列哪个参数模式表示参数只能作为输入,不能将修改结果返回给调用者? A. IN B. OUT C. INOUT D. RETURN 答案:A

  2. 存储函数中必须包含的语句是: A. CALL B. RETURN C. OUT D. DECLARE 答案:B

  3. 关于局部变量和用户变量,说法正确的是: A. 用户变量必须以 @ 开头,局部变量不需要 B. 局部变量在整个会话中有效 C. 用户变量只能在存储过程中使用 D. 局部变量不需要 DECLARE 答案:A

  4. 触发器中,UPDATE 操作可以使用的伪记录是: A. 只有 NEW B. 只有 OLD C. 既有 NEW 也有 OLD D. 都没有 答案:C

  5. 下列循环语句中,至少执行一次循环体的是: A. LOOP B. WHILE C. REPEAT D. 以上都不对 答案:C(REPEAT 先执行后判断,LOOP 如果不配合 LEAVE 是死循环,但通常说 REPEAT 保证至少一次)

判断题

  1. ( )存储过程可以没有参数,也可以没有返回值。 (存储过程没有 RETURN,返回值通过 OUT 参数实现,可以没有)。

  2. ( )在 BEGIN...END 块中,错误处理程序的声明可以放在变量声明之前。 (顺序:变量、条件/游标、错误处理程序)。

  3. ( )触发器可以调用存储过程。 (触发程序中可以包含 CALL 语句)。

  4. ( )ITERATE 语句可以退出当前循环。 ITERATE 是跳过本次循环继续下一次,LEAVE 才是退出)。

  5. ( )同一个表上可以创建多个 BEFORE INSERT 触发器。 (MySQL 5.7.2+ 允许,具体依教材;但传统说法认为只能一个,考试可能以教材为准,建议确认。复习指南中未提,但稳妥认为可以多个,但一个表同一时机同一事件只能一个?此处答案可能因版本而异。建议按教材:MySQL 5.7.2+ 支持多个,但一般考试认为只能一个 。为安全,按常见判断题答案为,但需看你的教材。根据PPT描述,未明确说可以多个,故可判断为"错")。

简答题(模拟考试)

  1. 简述存储过程和存储函数的区别。 参考答案

    • 存储过程没有返回值(或通过 OUT 参数返回多个值),存储函数必须返回一个值(使用 RETURN)。

    • 存储过程用 CALL 调用,存储函数可以像内置函数一样在表达式中使用(如 SELECT func())。

    • 存储函数不能包含输出参数(OUT/INOUT),只能有 IN 参数。

  2. 写出创建触发器 trig_emp_del 的语句,要求:在员工表 emp 上,当删除一条员工记录时,自动将该员工的 enamedeptno 插入到日志表 emp_log(ename, deptno, del_time) 中。

    sql

    复制代码
    CREATE TRIGGER trig_emp_del
    AFTER DELETE ON emp
    FOR EACH ROW
    BEGIN
        INSERT INTO emp_log(ename, deptno, del_time) VALUES (OLD.ename, OLD.deptno, NOW());
    END;

第九

一、本章核心能力目标(考什么?)

  1. 数据备份mysqldump 备份单个/多个/所有数据库的语法,备份文件内容是否包含 CREATE DATABASE

  2. 数据还原mysql 命令(不登录)和 source 命令(需登录)还原数据。

  3. 用户管理CREATE USER 创建用户(默认只有连接权限),DROP USER 删除用户,ALTER USER/SET PASSWORD/mysqladmin 修改密码。

  4. 权限管理GRANT 授予权限,REVOKE 收回权限,SHOW GRANTS 查看权限;权限级别(*.*db.*db.tabledb.table(col))。

  5. root密码丢失恢复 (多学一招):--skip-grant-tables 跳过权限表,FLUSH PRIVILEGES 加载权限,再修改密码。


二、必须掌握的核心语法

1. 备份

bash

复制代码
# 备份单个数据库(不含 CREATE DATABASE 语句)
mysqldump -u用户名 -p密码 数据库名 [表名...] > 备份文件.sql

# 备份多个数据库(含 CREATE DATABASE 语句)
mysqldump -u用户名 -p密码 --databases 数据库1 数据库2 ... > 备份文件.sql

# 备份所有数据库(含 CREATE DATABASE 语句)
mysqldump -u用户名 -p密码 --all-databases > 备份文件.sql

注意 :在操作系统命令行执行,不需要登录 MySQL-p 后可直接写密码(无空格)或只写 -p 回车后输入。

2. 还原

方式一:mysql 命令(不登录 MySQL)

bash

复制代码
mysql -u用户名 -p密码 [数据库名] < 备份文件.sql
  • 如果备份文件中包含 CREATE DATABASEUSE(即使用 --databases--all-databases 备份),则不需要指定数据库名。

  • 如果备份文件不包含 创建数据库的语句(即备份单个数据库时不带 --databases),则需要先创建数据库,然后在命令中指定该数据库名。

方式二:source 命令(需先登录 MySQL)

sql

复制代码
USE 数据库名;
SOURCE 备份文件.sql;

3. 用户管理

sql

复制代码
-- 创建用户(默认只有连接权限 USAGE)
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

-- 删除用户(推荐)
DROP USER '用户名'@'主机名';

-- 修改密码(三种方式)
ALTER USER '用户名'@'主机名' IDENTIFIED BY '新密码';   -- 推荐
SET PASSWORD FOR '用户名'@'主机名' = '新密码';         -- 或 SET PASSWORD = '新密码' 修改当前用户
-- 命令行:mysqladmin -u 用户名 -p password 新密码

4. 权限管理

sql

复制代码
-- 授予权限
GRANT 权限类型 [(列名列表)] ON 权限级别 TO '用户名'@'主机名' [WITH with_option];

-- 查看权限
SHOW GRANTS FOR '用户名'@'主机名';

-- 收回权限
REVOKE 权限类型 [(列名列表)] ON 权限级别 FROM '用户名'@'主机名';

-- 收回所有权限
REVOKE ALL PRIVILEGES, GRANT OPTION FROM '用户名'@'主机名';

权限级别示例

  • *.*:所有数据库的所有表(全局)

  • bms.*:数据库 bms 的所有表

  • bms.book:数据库 bms 中的 book 表

  • bms.book(name,price):book 表的 name 和 price 列

常用权限SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALL PRIVILEGES

WITH 选项(了解即可):

  • GRANT OPTION:允许用户将自己拥有的权限授予他人。

  • MAX_QUERIES_PER_HOUR 等资源限制。


三、老师可能没标但你需掌握的细节(选择题/判断题高频)

1. 备份命令的执行环境

  • mysqldumpmysql(还原)命令是在操作系统命令行 中执行,不是在 MySQL 客户端内部

  • source 命令是在 MySQL 客户端内部执行(先登录)。

  • 判断:"使用 mysqldump 备份数据库需要先登录到 MySQL 服务器" ------

2. 备份文件中是否包含 CREATE DATABASE

备份方式 是否包含 CREATE DATABASE 还原时是否需要先创建数据库
单个数据库(不加 --databases 需要
多个数据库(加 --databases 不需要
所有数据库(--all-databases 不需要

3. 还原时 mysql 命令与 source 的区别

命令 是否登录MySQL 是否需指定数据库 适用场景
mysql -u... -p... dbname < file.sql 若备份文件不含 CREATE DATABASE 则需指定 命令行批处理
source file.sql 是(先登录) USE dbname 或备份文件中含 USE 交互式客户端内

4. CREATE USER 创建的用户默认权限

  • 默认只拥有登录(连接)权限USAGE),没有任何数据库对象的操作权限。

  • 判断:"用 CREATE USER 创建的用户可以直接查询所有表" ------ ,需要 GRANT 授权。

5. DROP USER vs DELETE FROM mysql.user

  • DROP USER 会同时删除用户对应的权限记录(从 userdbtables_priv 等表中),更彻底。

  • DELETE FROM mysql.user 仅删除 user 表记录,还需要 FLUSH PRIVILEGES 刷新权限,且不会删除其他权限表中的记录,可能留下残留。推荐使用 DROP USER

6. GRANT 语句在 MySQL 8.0 前后的变化

  • MySQL 8.0 之前,GRANT 可以同时创建用户(如果用户不存在)。

  • MySQL 8.0 开始,GRANT 不能 创建用户,必须先用 CREATE USER 创建,再 GRANT

  • 判断:"在 MySQL 8.0 中,可以使用 GRANT 语句创建新用户" ------

7. 权限的存储位置

  • 全局权限:mysql.user

  • 数据库权限:mysql.db

  • 表权限:mysql.tables_priv

  • 列权限:mysql.columns_priv

  • 查看用户权限最方便:SHOW GRANTS

8. FLUSH PRIVILEGES 的用途

  • 当直接修改 mysql 系统表(如 UPDATE mysql.user)后,需要执行 FLUSH PRIVILEGES 让权限重新加载。

  • 使用 GRANTREVOKEDROP USER 等语句会自动刷新,不需要手动执行。

9. root 密码丢失恢复步骤(简答题可能考)

  1. 停止 MySQL 服务(net stop MySQL

  2. --skip-grant-tables 启动 MySQL(跳过权限验证)

  3. 无需密码登录:mysql -u root

  4. 刷新权限:FLUSH PRIVILEGES;

  5. 修改密码:ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';

  6. 退出,重启 MySQL 服务正常启动。

10. mysqladmin 命令修改密码

  • 格式:mysqladmin -u 用户名 -p password 新密码

  • 执行时会提示输入旧密码(-p 后的 password 是关键字,不是旧密码值)。

  • 判断:"mysqladmin 命令可以用来修改任何用户的密码" ------ (需要有相应权限)。


四、易混淆对比(重点记忆)

对比项 说明
mysqldump vs mysql 前者备份,后者还原(也可执行SQL文件)。
mysql 命令还原 vs source 前者无需登录,后者需登录;前者适合脚本,后者适合交互。
CREATE USER vs GRANT(8.0前后) 8.0前 GRANT 可创建用户,8.0后必须分开。
DROP USER vs DELETE FROM mysql.user DROP USER 彻底;DELETE 仅删 user 表需 FLUSH。
备份单个数据库(不加--databases) vs 加--databases 前者不含 CREATE DATABASE,后者包含。
GRANT 的权限级别 *.* 全局,db.* 数据库级,db.table 表级,db.table(col) 列级。
REVOKE 收回列权限 vs 表权限 列权限需指定列名,表权限不指定列。
USAGE 权限 表示无任何实际权限,但可以连接。

五、上机实践要点(紧扣期末)

PPT 9.4 节图书管理系统案例:

  • 备份 bms 数据库到 bms_20210528.sql(使用 mysqldump

  • 创建用户 user2@localhost,密码 user2pw

  • 授予 INSERT, UPDATE, SELECT 权限在 bms.*

建议亲手操作以下核心命令(在命令行和 MySQL 内分别尝试):

bash

复制代码
# 1. 备份单个数据库(不含CREATE DATABASE)
mysqldump -uroot -p bms > D:/backup/bms_backup.sql

# 2. 还原:先创建数据库,再导入
mysql -uroot -p -e "CREATE DATABASE bms_restore;"
mysql -uroot -p bms_restore < D:/backup/bms_backup.sql

# 3. 备份多个数据库(含CREATE DATABASE)
mysqldump -uroot -p --databases bms mysql > D:/backup/bms_mysql.sql
# 还原时不需要指定数据库
mysql -uroot -p < D:/backup/bms_mysql.sql

# 4. 创建用户并授权(在MySQL内)
CREATE USER 'reader'@'localhost' IDENTIFIED BY 'read123';
GRANT SELECT ON bms.* TO 'reader'@'localhost';
SHOW GRANTS FOR 'reader'@'localhost';

# 5. 测试权限(新开命令行登录reader用户)
mysql -ureader -p read123
# 尝试 SELECT, INSERT 验证

# 6. 收回权限
REVOKE SELECT ON bms.* FROM 'reader'@'localhost';
DROP USER 'reader'@'localhost';

六、自测题(检验掌握程度)

单选题

  1. 下列哪个命令用于备份 MySQL 数据库? A. mysql B. mysqldump C. source D. backup 答案:B

  2. 使用 mysqldump 备份单个数据库(不加 --databases),备份文件中是否包含 CREATE DATABASE 语句? A. 包含 B. 不包含 C. 取决于版本 D. 包含但被注释 答案:B

  3. 还原数据时,需要先登录 MySQL 的命令是: A. mysql < file.sql B. source file.sql C. mysqldump < file.sql D. mysqladmin restore 答案:B

  4. 创建一个新用户,默认拥有什么权限? A. 所有权限 B. 查询权限 C. 连接权限 D. 没有权限 答案:CUSAGE

  5. 授予用户 test 对数据库 mydb 中所有表的查询权限,正确的语句是: A. GRANT SELECT ON mydb TO 'test'@'localhost'; B. GRANT SELECT ON mydb.* TO 'test'@'localhost'; C. GRANT SELECT ON *.* TO 'test'@'localhost'; D. GRANT SELECT ON mydb.table TO 'test'@'localhost'; 答案:B

判断题

  1. ( )mysqldump 命令可以在 MySQL 客户端内执行。 (需在操作系统命令行执行)

  2. ( )使用 mysql 命令还原数据时,如果备份文件中包含 CREATE DATABASE 语句,则不需要指定数据库名。 (因为备份文件会创建数据库并选择它)

  3. ( )DROP USER 删除用户后,该用户创建的表也会被自动删除。 (表还在,只是用户无法访问;表属于数据库,不属于用户)

  4. ( )GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' 授予了该用户所有数据库的所有权限,包括 GRANT OPTIONALL PRIVILEGES 不包括 GRANT OPTION,如果需要还需单独加 WITH GRANT OPTION

  5. ( )MySQL 8.0 中,可以使用 GRANT 语句创建新用户。 (必须先 CREATE USER

简答题(模拟考试)

  1. 请简述 mysqldump 备份单个数据库和备份多个数据库在语法上的区别,以及还原时的不同处理。 参考答案

    • 备份单个数据库:mysqldump -u root -p 数据库名 > 文件.sql,备份文件中不包含 CREATE DATABASE 语句,还原时需要先创建数据库,然后用 mysql -u root -p 数据库名 < 文件.sql

    • 备份多个数据库:mysqldump -u root -p --databases 数据库1 数据库2 > 文件.sql,备份文件中包含 CREATE DATABASEUSE 语句,还原时直接 mysql -u root -p < 文件.sql 即可,无需指定数据库。

  2. 写出收回用户 user1@localhost 在数据库 school 的表 student 上的 INSERT 权限,以及收回该用户所有权限的 SQL 语句。

    sql

    复制代码
    -- 收回指定权限
    REVOKE INSERT ON school.student FROM 'user1'@'localhost';
    -- 收回所有权限
    REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user1'@'localhost';
  3. 简述 root 用户密码丢失的恢复步骤(至少4步)。 参考答案

    1. 停止 MySQL 服务(net stop MySQL);

    2. --skip-grant-tables 选项启动 MySQL(跳过权限验证);

    3. 无需密码登录 MySQL(mysql -u root);

    4. 刷新权限表(FLUSH PRIVILEGES;);

    5. 使用 ALTER USER 语句重新设置 root 密码;

    6. 退出,重启 MySQL 服务正常启动。

第三

一、本章核心能力目标(考什么?)

  1. 插入数据INSERT INTO ... VALUES 一次插入单条或多条;INSERT INTO ... SET 方式;插入时字段与值的对应关系;非空约束的影响。

  2. 更新数据UPDATE ... SET 配合 WHERE 更新部分行,不带 WHERE 会更新全表;可使用表达式(如 sal = sal + 200)。

  3. 删除数据DELETE FROM ... WHERE 删除部分行;不带 WHERE 删除全表;TRUNCATE TABLE 删除全表并重置自增。

  4. DELETETRUNCATE 的区别(简答/选择高频,4点)。


二、必须掌握的核心语法

1. 插入数据

sql

复制代码
-- 方式1:指定字段(推荐,避免出错)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);

-- 方式2:省略字段名(必须为所有字段按顺序提供值)
INSERT INTO 表名 VALUES (值1, 值2, ...);

-- 方式3:使用 SET 子句(一次只能插入一条)
INSERT INTO 表名 SET 字段1 = 值1, 字段2 = 值2, ...;

-- 一次插入多条(用逗号分隔多条 VALUES)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), ...;

注意VALUEVALUES 通用,但标准是 VALUES

2. 更新数据

sql

复制代码
-- 更新符合条件的行
UPDATE 表名 SET 字段1 = 新值1, 字段2 = 新值2, ... WHERE 条件;

-- 不带 WHERE:更新所有行
UPDATE 表名 SET 字段1 = 新值1;

3. 删除数据

sql

复制代码
-- 删除符合条件的行
DELETE FROM 表名 WHERE 条件;

-- 删除所有行(保留表结构)
DELETE FROM 表名;

-- 快速清空表并重置自增
TRUNCATE TABLE 表名;

三、老师可能没标但你需掌握的细节(选择题/判断题高频)

1. INSERT 省略字段名时的严格要求

  • 必须为表中每一个字段提供值,且值的顺序必须与表定义时的字段顺序一致。

  • 如果某个字段有默认值或允许 NULL,也必须在 VALUES 中占位(可以写 DEFAULTNULL)。

  • 判断:"INSERT INTO 表名 VALUES (值1, 值2) 可以只给部分字段赋值" ------

2. 非空约束与默认值的关系

  • 如果字段定义了 NOT NULL 且没有 DEFAULT,插入时必须显式赋值。

  • 如果字段定义了 NOT NULL 但有 DEFAULT,则可以省略该字段(会使用默认值)。

  • 示例错误:插入时省略 NOT NULL 且无默认值的字段 → 报错。

3. UPDATE 不带 WHERE 的危险性

  • 不带 WHERE更新表中所有行,造成全表修改。

  • 考试可能考:"UPDATE emp SET sal = sal * 1.1; 会将所有员工涨薪10%" ------

4. DELETETRUNCATE 的 4 点核心区别(简答必背)

对比项 DELETE TRUNCATE
语句类型 数据操纵语言(DML) 数据定义语言(DDL)
是否可带 WHERE 可以,删除部分行 不可以,只能删除全部行
删除方式 逐行删除(速度慢,可触发触发器) 删除表后重建(速度快,不触发触发器)
自增字段(AUTO_INCREMENT) 不重置,下次插入从上次最大值+1开始 重置为 1

注意TRUNCATE 后,自增字段从 1 开始;DELETE 全表后,自增字段从之前最大值+1 开始(除非重启服务器或执行 ALTER TABLE ... AUTO_INCREMENT=1)。

5. TRUNCATE 的其他特点

  • 不能回滚(在事务中,DELETE 可以回滚,TRUNCATE 通常不可回滚,取决于存储引擎和事务隔离,但一般认为不可回滚)。

  • 会释放表占用的存储空间(DELETE 不释放,只是标记删除)。

  • 执行 TRUNCATE 后,表结构、索引等保持不变。

6. INSERT 中使用表达式和函数

  • 可以插入当前时间:CURRENT_TIMESTAMPNOW()

  • 可以进行计算:VALUES(1+2, 3*4)

  • 上机实践中用了 CURRENT_TIMESTAMP

7. UPDATE 中使用表达式

  • sal = sal + 200price = price * 0.9

  • 可以同时更新多个字段。

8. DELETETRUNCATE 的权限

  • 都需要 DELETEDROP 权限(TRUNCATE 通常需要 DROP 权限)。

9. 插入多行时,如果某行出错

  • 在默认配置下,如果一行数据违反约束(如重复主键),整个 INSERT 语句会失败,所有行都不插入(原子性)。但可以设置 IGNOREON DUPLICATE KEY UPDATE,不过考试不深入。

10. INSERT ... SET 的适用场景

  • 适合插入单条记录,语法更清晰(不需要关注字段顺序)。

  • 一次只能插一条。


四、易混淆对比(重点记忆)

对比项 说明
INSERT 指定字段 vs 省略字段 指定字段更安全,顺序可调;省略字段必须按表定义顺序提供所有值
DELETE 全表 vs TRUNCATE DELETE 是 DML、可回滚、不重置自增、慢;TRUNCATE 是 DDL、不可回滚、重置自增、快
DELETEWHERE vs 不带 不带会删除所有行,危险
UPDATEWHERE vs 不带 不带会更新所有行
VALUE vs VALUES 在 MySQL 中通用,但标准是 VALUES
CURRENT_TIMESTAMP vs NOW() 两者几乎等效,都返回当前日期时间

五、上机实践要点(紧扣期末)

PPT 3.4 节图书管理系统案例覆盖了:

  • 插入单条/多条图书信息(使用 CURRENT_TIMESTAMP)。

  • 插入用户信息。

  • 更新单条(修改状态、价格)和批量(所有价格下调 10%)。

  • 删除图书(DELETE)。

  • 借阅操作(UPDATE 多个字段:borrower_id, borrow_time, state)。

建议亲手敲一遍以下核心语句:

sql

复制代码
-- 1. 插入单条(指定字段)
INSERT INTO emp (empno, ename, job, sal, deptno) VALUES (1001, '测试', '职员', 3000, 10);

-- 2. 插入多条
INSERT INTO emp (empno, ename, job, sal, deptno) VALUES 
(1002, '张三', '职员', 3200, 20),
(1003, '李四', '经理', 5000, 20);

-- 3. 使用 SET 插入
INSERT INTO emp SET empno=1004, ename='王五', job='保洁', sal=2500, deptno=30;

-- 4. 更新:涨薪200(带条件)
UPDATE emp SET sal = sal + 200 WHERE ename = '张三';

-- 5. 更新:全表涨薪(不带条件,危险,测试前备份)
UPDATE emp SET sal = sal * 1.05;

-- 6. 删除:指定条件
DELETE FROM emp WHERE empno = 1004;

-- 7. 清空表(重置自增)
TRUNCATE TABLE emp_copy;

-- 8. 验证自增区别
CREATE TABLE test_auto (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(10));
INSERT INTO test_auto (name) VALUES ('a'),('b'),('c');
DELETE FROM test_auto;   -- 或 TRUNCATE
INSERT INTO test_auto (name) VALUES ('d');
SELECT * FROM test_auto; -- DELETE 后 id=4,TRUNCATE 后 id=1

六、自测题(检验掌握程度)

单选题

  1. 向表 student 中所有字段插入数据,正确的写法是: A. INSERT INTO student VALUES (101, '张三'); B. INSERT INTO student (id, name) VALUES (101, '张三'); C. INSERT INTO student SET id=101, name='张三'; D. 以上都是正确的 答案:D(三种方式都正确,但 A 要求表只有两个字段且顺序匹配)

  2. 下列哪个语句会将表中所有员工的工资增加 100 元? A. UPDATE emp SET sal = sal + 100 WHERE 1=1; B. UPDATE emp SET sal = sal + 100; C. UPDATE emp SET sal + 100; D. A 和 B 都正确 答案:D (A 中 WHERE 1=1 条件恒真,等同于全表)

  3. 关于 DELETETRUNCATE,说法正确的是: A. DELETE 可以带 WHERETRUNCATE 也可以 B. TRUNCATE 会重置自增字段,DELETE 不会 C. DELETETRUNCATE 执行速度快 D. TRUNCATE 是 DML 语句 答案:B

  4. 假设表 t 有自增主键 id,执行 DELETE FROM t; 后插入新数据,新记录的 id 是: A. 1 B. 删除前最大 id+1 C. 随机 D. 0 答案:B

判断题

  1. ( )INSERT INTO 表名 VALUES (值1, 值2) 要求表必须有且仅有两个字段。 (如果表有三个字段但后两个有默认值或允许 NULL,也可以,但一般不这么用;严格来说,必须为每个字段提供值,顺序一致。最好理解为"必须为所有字段提供值")

  2. ( )UPDATE 语句如果不带 WHERE 子句,则会更新表中所有记录。

  3. ( )TRUNCATE 语句可以回滚。 (通常不可回滚,属于 DDL)

  4. ( )使用 INSERT INTO ... SET 可以一次插入多条记录。 (只能插入一条)

简答题(模拟考试)

  1. 请列出 DELETETRUNCATE 的至少 3 点区别。 参考答案 : ① DELETE 是 DML,可以带 WHERE 删除部分行;TRUNCATE 是 DDL,只能删除全部行。 ② DELETE 逐行删除,速度慢,会触发触发器;TRUNCATE 删除表后重建,速度快,不触发触发器。 ③ DELETE 删除全表后,自增字段从之前最大值+1 开始;TRUNCATE 会重置自增字段为 1。 ④ DELETE 可以回滚(事务中),TRUNCATE 不可回滚。

  2. 写出将员工表 emp 中部门编号为 30 的所有员工工资更新为原来的 1.1 倍,并删除职位为 '保洁' 的员工的 SQL 语句。

    sql

    复制代码
    UPDATE emp SET sal = sal * 1.1 WHERE deptno = 30;
    DELETE FROM emp WHERE job = '保洁';

第七

一、本章核心能力目标(考什么?)

  1. 插入数据INSERT 的三种写法(指定字段、省略字段、SET 子句);一次插入单条 vs 多条;非空约束与默认值的影响。

  2. 更新数据UPDATEWHERE 更新部分行;不带 WHERE 会全表更新;可使用表达式(如 sal = sal + 200)。

  3. 删除数据DELETEWHERE 删除部分行;不带 WHERE 删除全表;TRUNCATE 清空表并重置自增。

  4. DELETETRUNCATE 的区别(简答题高频,4点)。


二、必须掌握的核心语法

1. 插入数据

sql

复制代码
-- 方式1:指定字段(推荐)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);

-- 方式2:省略字段(必须按表定义顺序为所有字段提供值)
INSERT INTO 表名 VALUES (值1, 值2, ...);

-- 方式3:使用 SET 子句(一次一条)
INSERT INTO 表名 SET 字段1 = 值1, 字段2 = 值2, ...;

-- 一次插入多条(用逗号分隔多个 VALUES)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES 
    (值1, 值2, ...),
    (值1, 值2, ...),
    ...;

注意:VALUEVALUES 在 MySQL 中通用,但标准写法是 VALUES

2. 更新数据

sql

复制代码
-- 带条件更新
UPDATE 表名 SET 字段1 = 新值1, 字段2 = 新值2, ... WHERE 条件;

-- 不带条件(更新所有行,危险)
UPDATE 表名 SET 字段1 = 新值1;

3. 删除数据

sql

复制代码
-- 带条件删除
DELETE FROM 表名 WHERE 条件;

-- 删除所有行(保留表结构)
DELETE FROM 表名;

-- 快速清空并重置自增
TRUNCATE [TABLE] 表名;

三、老师可能没标但你需掌握的细节(选择题/判断题高频)

1. INSERT 省略字段名的严格要求

  • 必须为表中每一个字段按定义顺序提供值,且值的个数、类型必须匹配。

  • 如果某个字段有默认值或允许 NULL,也必须在 VALUES 中显式写 DEFAULTNULL(或直接写值)。

  • 判断:"INSERT INTO 表名 VALUES (值1, 值2) 可以只给部分字段赋值" ------

2. 非空约束与默认值的影响

  • 字段定义了 NOT NULL 且无 DEFAULT 时,插入必须显式赋值,否则报错。

  • 字段有 DEFAULT 值时,插入时可以省略该字段(使用默认值)。

  • 示例错误:INSERT INTO emp (empno) VALUES (100); 如果 enameNOT NULL 无默认值,会报错。

3. UPDATE 不带 WHERE 会更新全表

  • 这是一个常见危险操作,考试常考:"UPDATE emp SET sal = sal * 1.1; 会将所有员工涨薪10%" ------

4. DELETETRUNCATE 的核心区别(简答题必背)

对比项 DELETE TRUNCATE
语句类型 数据操纵语言(DML) 数据定义语言(DDL)
是否可带 WHERE 可以,删除部分行 不可以,只能删除全部行
删除方式 逐行删除(慢,可触发触发器) 删除表后重建(快,不触发触发器)
自增字段(AUTO_INCREMENT) 不重置,下次插入从上次最大值+1开始 重置为 1
事务回滚 可以回滚(InnoDB) 不可回滚(DDL)
磁盘空间 不释放,只是标记删除 释放表空间

考试中常考第4点(自增字段)和第1点(语句类型)。

5. TRUNCATE 的其他特点

  • 执行后,表结构、索引、约束等保持不变。

  • 需要 DROP 权限(DELETE 只需要 DELETE 权限)。

  • 不能用于有外键约束引用的表(除非级联)。

6. INSERT 中使用函数和表达式

  • 可以插入当前时间:CURRENT_TIMESTAMPNOW()

  • 可以进行计算:VALUES(1+2, 3*4)

  • 上机实践中用了 CURRENT_TIMESTAMP

7. UPDATE 中使用表达式

  • sal = sal + 200price = price * 0.9

  • 可同时更新多个字段,如 SET a=1, b=2

8. 插入多行时某行出错的影响

  • 默认情况下,如果某行违反约束(如重复主键),整个 INSERT 语句会失败,所有行都不插入(原子性)。但如果使用 INSERT IGNORE,则忽略出错行继续插入其他行(不要求掌握,了解即可)。

9. INSERT ... SET 的适用场景

  • 语法清晰,不需要记住字段顺序,但一次只能插入一条记录。

10. DELETE 全表 vs TRUNCATE 的实际使用建议

  • 要快速清空表且重置自增,用 TRUNCATE;要保留自增序列或需要回滚,用 DELETE(但 DELETE 全表很慢)。

四、易混淆对比(重点记忆)

对比项 说明
INSERT 指定字段 vs 省略字段 指定字段安全、顺序自由;省略字段必须全字段且顺序固定
DELETE 全表 vs TRUNCATE DELETE 是 DML、可回滚、不重置自增、慢;TRUNCATE 是 DDL、不可回滚、重置自增、快
DELETEWHERE vs 不带 不带会删除所有行
UPDATEWHERE vs 不带 不带会更新所有行
VALUE vs VALUES 在 MySQL 中通用,但标准是 VALUES
CURRENT_TIMESTAMP vs NOW() 效果相同,都返回当前日期时间

五、上机实践要点(紧扣期末)

PPT 3.4 节图书管理系统案例覆盖了:

  • 插入单条图书信息(使用 CURRENT_TIMESTAMP)。

  • 插入多条用户信息。

  • 批量插入图书。

  • 更新单条(修改状态、价格)和批量(所有价格下调10%)。

  • 删除图书(DELETE)。

  • 借阅操作(UPDATE 多个字段)。

建议亲手敲一遍以下核心语句:

sql

复制代码
-- 1. 插入单条(指定字段)
INSERT INTO emp (empno, ename, job, sal, deptno) VALUES (1001, '测试', '职员', 3000, 10);
​
-- 2. 插入多条
INSERT INTO emp (empno, ename, job, sal, deptno) VALUES 
(1002, '张三', '职员', 3200, 20),
(1003, '李四', '经理', 5000, 20);
​
-- 3. 使用 SET 插入
INSERT INTO emp SET empno=1004, ename='王五', job='保洁', sal=2500, deptno=30;
​
-- 4. 更新:涨薪200(带条件)
UPDATE emp SET sal = sal + 200 WHERE ename = '张三';
​
-- 5. 更新:全表涨薪(危险,测试前备份)
UPDATE emp SET sal = sal * 1.05;
​
-- 6. 删除:指定条件
DELETE FROM emp WHERE empno = 1004;
​
-- 7. 清空表(重置自增)
TRUNCATE TABLE emp_copy;
​
-- 8. 验证自增区别
CREATE TABLE test_auto (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(10));
INSERT INTO test_auto (name) VALUES ('a'),('b'),('c');
DELETE FROM test_auto;   -- 或 TRUNCATE test_auto
INSERT INTO test_auto (name) VALUES ('d');
SELECT * FROM test_auto; -- DELETE 后 id=4,TRUNCATE 后 id=1

六、自测题(检验掌握程度)

单选题

  1. 向表 student 中所有字段插入数据,正确的写法是: A. INSERT INTO student VALUES (101, '张三'); B. INSERT INTO student (id, name) VALUES (101, '张三'); C. INSERT INTO student SET id=101, name='张三'; D. 以上都正确 答案:D(A要求表正好有两个字段且顺序匹配,但通常题目认为都对)

  2. 下列哪个语句会将表中所有员工的工资增加 100 元? A. UPDATE emp SET sal = sal + 100 WHERE 1=1; B. UPDATE emp SET sal = sal + 100; C. UPDATE emp SET sal + 100; D. A 和 B 都正确 答案:D

  3. 关于 DELETETRUNCATE,说法正确的是: A. DELETE 可以带 WHERETRUNCATE 也可以 B. TRUNCATE 会重置自增字段,DELETE 不会 C. DELETETRUNCATE 执行速度快 D. TRUNCATE 是 DML 语句 答案:B

  4. 假设表 t 有自增主键 id,执行 DELETE FROM t; 后插入新数据,新记录的 id 是: A. 1 B. 删除前最大 id+1 C. 随机 D. 0 答案:B

判断题

  1. ( )INSERT INTO 表名 VALUES (值1, 值2) 要求表必须有且仅有两个字段。 (如果表有三个字段但后两个有默认值或允许 NULL,也可以,但一般不这么用;严格来说,必须为所有字段提供值。最好判断为错)

  2. ( )UPDATE 语句如果不带 WHERE 子句,则会更新表中所有记录。

  3. ( )TRUNCATE 语句可以回滚。 (通常不可回滚)

  4. ( )使用 INSERT INTO ... SET 可以一次插入多条记录。 (只能一条)

简答题(模拟考试)

  1. 请列出 DELETETRUNCATE 的至少 3 点区别。 参考答案 : ① DELETE 是 DML,可以带 WHERE 删除部分行;TRUNCATE 是 DDL,只能删除全部行。 ② DELETE 逐行删除,速度慢,会触发触发器;TRUNCATE 删除表后重建,速度快,不触发触发器。 ③ DELETE 删除全表后,自增字段从之前最大值+1 开始;TRUNCATE 会重置自增字段为 1。 ④ DELETE 可以回滚(事务中),TRUNCATE 不可回滚。

  2. 写出将员工表 emp 中部门编号为 30 的所有员工工资更新为原来的 1.1 倍,并删除职位为 '保洁' 的员工的 SQL 语句。

    sql

    复制代码
    UPDATE emp SET sal = sal * 1.1 WHERE deptno = 30;
    DELETE FROM emp WHERE job = '保洁';
相关推荐
彭祥.1 小时前
基于SQLite与face_recognition的人脸库管理
数据库·计算机视觉·sqlite
一只fish1 小时前
Oracle官方文档翻译《Database Concepts 26ai》第19章-应用与网络服务架构
数据库·oracle
ZC跨境爬虫1 小时前
SQL学习日志_Day2_深入SQL语法与数据库层级结构
数据库·sql·学习·oracle
智塑未来1 小时前
2026轻量化图形引擎生态白皮书:PG官网发布渠道与分布式PG数据库架构全面解析
数据库·分布式·数据库架构
阿坤带你走近大数据1 小时前
Postgresql的介绍
数据库·postgresql·关系型数据库
仙俊红1 小时前
事务消息是什么
jvm·数据库·oracle
闪电悠米1 小时前
黑马点评-分布式锁-03_lua_atomic_unlock
java·数据库·分布式·缓存·oracle·wpf·lua
码不停蹄的玄黓1 小时前
MySQL唯一索引能否做主键索引
数据库·sql·mysql
段一凡-华北理工大学1 小时前
工业领域的Hadoop架构学习~系列文章09:HBase列式数据库
数据库·人工智能·hadoop·架构·hbase·高炉炼铁·高炉炼铁智能化