当前位置:首页>复习资料>软考数据库系统工程师 - 案例题复习资料

软考数据库系统工程师 - 案例题复习资料

  • 2026-05-13 18:39:39
软考数据库系统工程师 - 案例题复习资料

一、E-R图与关系模式设计

考点本质

E-R图设计考查的是从现实世界需求到抽象数据模型的转换能力。核心在于识别实体、联系、属性三要素,并正确判断联系类型(1:1、1:n、n:m、三元联系)。

1.1 核心知识体系

实体-联系模型三要素

要素
图形表示
本质含义
识别技巧
实体
矩形(▭)
现实世界中可独立存在的事物
找需求描述中的名词(人、物、地点、组织)
属性
椭圆(◯)
实体的特征或性质
描述实体特征的形容词/名词
联系
菱形(◇)
实体之间的关联关系
找需求描述中的动词短语

联系类型的本质区别

联系类型
数学含义
关系模式处理
典型场景
1:1
双射关系
将一方主键加入另一方
班级-班长、员工-工位
1:n
单射关系
将1方主键加入n方作为外键
学院-学生、部门-员工
n:m
多对多关系
必须单独成表
学生-课程、商品-订单
n:m:p
三元关系
单独成表,三方主键联合
供应商-零件-项目

E-R图转关系模式的本质规则

核心原则:联系的语义决定转换方式

情况
转换规则
主键
本质原因
实体
每个实体转成一个关系模式
实体的主键
实体独立存在
1:1联系
将一方主键加入另一方
任选一方主键
双向唯一确定
1:n联系
将1方主键加入n方
n方原主键
n方依赖1方
n:m联系单独成一个关系模式双方主键的联合
双方互相独立,需第三方关联
n:m:p三元联系
单独成一个关系模式
三方主键的联合
三方互相独立
联系有属性
联系的属性加入联系对应的关系模式
-
属性属于联系本身

1.2 考点深挖:联系类型的判断技巧

判断口诀

"一个A对应一个B" → 1:1
"一个A对应多个B,一个B对应一个A" → 1:n
"一个A对应多个B,一个B对应多个A" → n:m
"三个实体互相独立,通过同一事件关联" → 三元联系

典型误判分析

易错场景
错误判断
正确判断
分析
订单与商品
订单包含商品(1:n)
订单与商品是n:m
一个订单有多个商品,一个商品可在多个订单中
员工与项目
员工参与项目(n:m)
需看是否有"担任角色"等属性
如有角色属性,三元联系更合适
学生与班级
学生属于班级(n:1)
正确
但班级与班主任是1:1

深挖1:实体 vs 联系的区分本质

核心问题:什么时候应该设计为实体?什么时候应该设计为联系?

特征
实体
联系
是否有独立属性
独立属性
一般没有,或只有少量描述性属性
是否有独立标识
自己的主键
主键由关联实体的主键组成
生命周期
独立存在
依赖于关联实体
典型例子
订单(有订单号、日期、金额)
购买(只有购买时间、数量)

判断技巧

  • 如果它有自己独立的编号/标识 → 实体
  • 如果它只是为了描述两个实体之间的关系 → 联系
  • 如果它有复杂的属性需要记录 → 实体

深挖2:联系属性的归属问题

本质:联系属性属于联系本身,不属于任何一方实体。常见错误

错误:将"成绩"放在学生表中
正确:"成绩"放在选课联系表中

错误:将"采购数量"放在供应商表中
正确:"采购数量"放在采购联系表中

判断原则

  • 属性描述的是实体的特征 → 属于实体
  • 属性描述的是关系的特征 → 属于联系
  • 属性同时涉及双方 → 属于联系

深挖3:三元联系 vs 三个二元联系

本质区别

  • 三个二元联系
    :A-B、B-C、A-C 是独立的,可以单独存在
  • 三元联系
    :A、B、C 必须通过同一个事件关联,缺一不可

判断方法

如果 "某个A的某个B可以从某个C获取" → 三元联系
如果 "A和B有关系,B和C有关系,A和C也有关系" → 三个二元联系

示例对比

场景
联系类型
原因
供应商-零件-项目
三元联系
"某供应商为某项目供应某零件"是完整语义
学生-课程-教师
三个二元联系
学生选课、教师授课、教师指导学生是独立关系

深挖4:1:1联系的处理策略

三种处理方式

方式
适用场景
优点
缺点
合并到A表
A的查询频率高
减少连接操作
B表需要外键
合并到B表
B的查询频率高
减少连接操作
A表需要外键
单独成表
双方查询频率相近
结构清晰
需要额外连接

考试技巧:如果没有特别说明,任选一方合并即可,但通常选择将可选端(0..1)合并到强制端(1..1)。

1.3 举一反三:特殊场景处理

场景1:弱实体(Weak Entity)

本质:弱实体是依赖于强实体存在的实体,自身没有完整的主键。识别特征

  • 弱实体的存在依赖于另一个实体
  • 弱实体的主键需要加上强实体的主键

典型案例

  • 员工(强实体)- 家属(弱实体)
  • 订单(强实体)- 订单明细(弱实体)

关系模式

员工(员工编号,姓名,...)
家属(员工编号,家属姓名,关系,出生日期)
     ↑外键参照员工表

场景2:自反联系(Recursive Relationship)

本质:同一实体集内部的联系。典型案例

  • 员工的管理关系(1:n)
  • 零件的组成关系(n:m,爆炸图)

关系模式

员工(员工编号,姓名,领导编号)
            ↑外键参照本表员工编号

场景3:多值属性(Multivalued Attribute)

本质:一个实体可以有多个相同类型的属性值。识别特征

  • 需求描述中出现"多个"、"若干"等词
  • 属性值之间没有顺序关系

处理方式:将多值属性独立成表典型案例

学生(学号,姓名)
兴趣爱好(学号,兴趣爱好)
          ↑联合主键

场景4:三元联系的识别与处理

本质:三个实体之间的关联,不能拆分为两两之间的联系识别技巧

  • 需求描述中出现"某A的某B可以从某C获取"
  • 三个实体之间是互相独立

典型案例:供应商-零件-车型采购系统

采购(车型编号,供应商名称,零件编码,采购数量,采购日期)
      ↑三方主键联合

1.4 真题映射(考点落地)

【2023年-汽车零件采购系统】

  • 考点
    :三元联系识别
  • 深挖
    :为什么不是三个两两联系?因为"某个车型的某种零件可以从多家供应商采购",车型、零件、供应商三者是互相独立的,必须通过三元联系才能表达这种语义。

【2022年-疫苗接种系统】

  • 考点
    :n:m联系+联系属性
  • 深挖
    :被接种者与医院是n:m,联系属性"接种日期"属于联系本身,不属于任何一方实体。

【2021年-社区蔬菜团购网站】

  • 考点
    :实体 vs 联系的区分
  • 深挖
    :订单本身有独立属性(订单号、日期),所以订单应设计为实体,而非客户与团购点之间的简单联系。

1.5 答题模板

模板1:E-R图补全题

步骤1:识别已有实体和联系
步骤2:分析需求中未表示的实体间关系
步骤3:判断联系类型(1:1、1:n、n:m)
步骤4:确定联系属性(如有)
步骤5:用标准符号补全E-R图

模板2:关系模式补全题

步骤1:确定联系类型
步骤2:n:m联系→单独成表,双方主键+联系属性
步骤3:1:n联系→将1方主键加入n方
步骤4:标注主键(下划线)和外键(→参照)

二、SQL语句补充

考点本质

SQL语句补充考查的是用结构化查询语言表达数据操作的能力。核心在于理解DDL(数据定义)和DML(数据操纵)的语法细节,特别是完整性约束的定义和复杂查询的构建。

2.1 核心知识体系

DDL的本质:定义数据的"规则"

CREATE TABLE不仅是创建表,更是定义数据的完整性规则

约束类型
本质
作用
考试重点
PRIMARY KEY
实体完整性
唯一标识每条记录
单字段/联合主键
UNIQUE
实体完整性
不允许重复值
与主键的区别
REFERENCES
参照完整性
建立表间关联
外键简写vs完整写法
ON DELETE CASCADE
参照完整性
级联操作
删除/更新时的行为
NOT NULL
用户定义完整性
必填字段
与DEFAULT的配合
CHECK
用户定义完整性
自定义规则
范围、枚举、表达式
DEFAULT
用户定义完整性
默认值
与NOT NULL的区别

DML的本质:从数据中提取信息

复杂查询的构建逻辑:

查询目标 → 需要哪些表 → 表间如何关联 → 筛选条件 → 分组聚合 → 排序输出
查询技术
本质
适用场景
关键语法
多表连接
横向扩展数据
需要多个表的字段
WHERE 连接条件
外连接
保留未匹配记录
需要显示NULL情况
LEFT/RIGHT OUTER JOIN
子查询
嵌套查询
条件依赖于另一查询结果
IN/EXISTS/比较运算符
分组统计
聚合计算
按组汇总
GROUP BY + HAVING
集合运算
合并结果集
多个查询结果的并/交/差
UNION/INTERSECT/EXCEPT
视图
封装复杂查询
简化常用查询
CREATE VIEW

2.2 考点深挖:易混淆概念辨析

深挖1:PRIMARY KEY vs UNIQUE

对比项
PRIMARY KEY
UNIQUE
唯一性
非空性
✓(自动NOT NULL)
可空
每张表数量
只能有1个
可以有多个
本质
记录的唯一标识
业务上的唯一约束

考试陷阱

-- 错误:以为UNIQUE会自动NOT NULL
Cname CHAR(30) UNIQUE  -- Cname可以为NULL

-- 正确:如果需要非空+唯一
Cname CHAR(30) NOT NULL UNIQUE

深挖2:外键的两种写法

写法
语法
适用场景
简写Sno CHAR(10) REFERENCES Student(Sno)
单列外键
完整FOREIGN KEY (Sno) REFERENCES Student(Sno)
联合外键、需命名约束

考试陷阱

-- 错误:联合外键不能用简写
PRIMARY KEY (Sno, Cno)  -- 这是表级约束

-- 正确:联合外键必须用表级约束
FOREIGN KEY (Sno) REFERENCES Student(Sno)

深挖3:WHERE vs HAVING

子句
作用对象
可用表达式
执行时机
WHERE
列、常量、运算符
分组前
HAVING
聚合函数、列
分组后

记忆口诀:WHERE筛行,HAVING筛组;聚合条件只能用HAVING。

深挖4:IN vs EXISTS

运算符
本质
适用场景
性能特点
IN
判断值是否在集合中
子查询返回少量值
子查询结果集小时效率高
EXISTS
判断子查询是否有结果
子查询返回大量值
找到第一个匹配就停止

经典应用:"选修了全部课程的学生"

-- 双重NOT EXISTS:不存在一门课程该学生没有选修
SELECT Sname FROM Student S
WHERE NOT EXISTS (
    SELECT * FROM Course C
    WHERE NOT EXISTS (
        SELECT * FROM SC
        WHERE SC.Sno = S.Sno AND SC.Cno = C.Cno
    )
);

深挖5:连接类型的本质区别

连接类型
本质
结果特点
适用场景
INNER JOIN
只保留匹配的记录
无NULL值
只关心有关联的数据
LEFT JOIN
保留左表所有记录
右表不匹配则为NULL
需要显示左表全部数据
RIGHT JOIN
保留右表所有记录
左表不匹配则为NULL
需要显示右表全部数据
FULL JOIN
保留双方所有记录
不匹配处均为NULL
需要显示双方全部数据
CROSS JOIN
笛卡尔积
行数=左表行数×右表行数
生成所有组合

记忆技巧

  • INNER = 交集
  • LEFT = 左表全集 + 右表匹配部分
  • RIGHT = 右表全集 + 左表匹配部分
  • FULL = 并集

深挖6:NULL值的陷阱

NULL的本质:未知值、不存在值、未定义值

操作
结果
原因
NULL = NULL
NULL(不是TRUE)
未知是否等于未知
NULL <> NULL
NULL(不是TRUE)
未知是否不等于未知
5 + NULL
NULL
未知加5等于未知
COUNT(*)
包含NULL行
计数所有行
COUNT(列)
不包含NULL
只计数非NULL值
AVG(列)
不包含NULL
只计算非NULL值的平均

考试陷阱

-- 错误:以为这样可以筛选NULL
WHERE 列 = NULL  -- 永远返回FALSE

-- 正确:必须使用IS NULL
WHERE 列 IS NULL

-- 错误:以为NOT IN会包含NULL
WHERE 列 NOT IN (1, 2, NULL)  -- 永远返回FALSE

-- 正确:排除NULL后再判断
WHERE 列 IS NOT NULL AND 列 NOT IN (1, 2)

深挖7:聚合函数与空值

函数
处理NULL方式
结果为空表时
COUNT(*)
计数所有行,包括NULL
返回0
COUNT(列)
只计数非NULL值
返回0
SUM(列)
忽略NULL值
返回NULL
AVG(列)
忽略NULL值,分母减1
返回NULL
MAX/MIN
忽略NULL值
返回NULL

注意:SUM和AVG忽略NULL,但COUNT(列)也忽略NULL,这是容易混淆的地方。

深挖8:SQL执行顺序(理解查询的本质)

SELECT DISTINCT 列, 聚合函数          -- 5. 选择列,去重
FROM 表A JOIN 表B ON 条件            -- 1. 先连接表
WHERE 行筛选条件                      -- 2. 筛选行
GROUP BY 分组列                       -- 3. 分组
HAVING 组筛选条件                     -- 4. 筛选组
ORDER BY 排序列                       -- 6. 排序
LIMIT n;                              -- 7. 限制结果数

理解这个顺序的重要性

  • WHERE不能用聚合函数(因为聚合在GROUP BY之后)
  • SELECT中定义的别名不能在WHERE中使用(因为SELECT在WHERE之后执行)
  • HAVING可以用SELECT中的别名(因为HAVING在SELECT之后执行)

2.3 举一反三:SQL语句变式训练

变式1:自连接的不同写法

场景:查询每门课程的间接先修课

-- 写法1:显式JOIN
SELECT K1.Cno, K2.Cpno
FROM COURSE K1 LEFT OUTER JOIN COURSE K2
ON K1.Cpno = K2.Cno;

-- 写法2:隐式连接(WHERE)
SELECT K1.Cno, K2.Cpno
FROM COURSE K1, COURSE K2
WHERE K1.Cpno = K2.Cno;

-- 考点:LEFT OUTER JOIN保留NULL,隐式连接不保留

变式2:批量插入的多种方式

-- 方式1:为所有学生插入一门新课程
INSERT INTO SC(Sno, Cno)
SELECT Sno, 'C036'
FROM STUDENT;

-- 方式2:从另一表复制数据
INSERT INTO SC(Sno, Cno)
SELECT Sno, Cno FROM SC_TEMP;

-- 方式3:插入常量值
INSERT INTO SC(Sno, Cno)
SELECT Sno, 'C036'
FROM STUDENT
WHERE Sdept = '计算机';

变式3:视图的多层嵌套

-- 基础视图:已售商品统计
CREATE VIEW GOODS_SOLD AS
SELECT Gno, COUNT(*) AS Onum, SUM(Onumber) AS Total
FROM ORDERS
GROUP BY Gno;

-- 上层视图:结合商品信息
CREATE VIEW GOODS_REPORT AS
SELECT G.Gno, G.Gname, S.Onum, S.Total
FROM GOODS G, GOODS_SOLD S
WHERE G.Gno = S.Gno;

2.4 真题映射(考点落地)

【2023年-教务管理系统】

  • 考点
    :自参照外键
  • 深挖
    :课程表的先修课参照本表,这是自反联系在SQL中的实现。注意REFERENCES后面是COURSE(Cno),不是Cpno

【2022年-工程项目管理系统】

  • 考点
    :CHECK约束
  • 深挖
    :CHECK不仅是范围检查,还可以是枚举检查(CHECK (Rank IN ('一','二','三','无')))。

【2021年-竞赛管理系统】

  • 考点
    :联合主键
  • 深挖
    :联合主键的语法是PRIMARY KEY (Pno, Cno),不是PRIMARY KEY Pno, Cno

2.5 答题模板

模板1:CREATE TABLE完整框架

CREATE TABLE 表名(
    列1 类型 [约束],                    -- 主键列
    列2 类型 REFERENCES 父表(列),      -- 外键列(简写)
    列3 类型 NOT NULL,                  -- 非空列
    列4 类型 UNIQUE,                    -- 唯一列
    列5 类型 CHECK(条件),               -- 检查约束
    列6 类型 DEFAULT '值',              -- 默认值
    [表级约束]
);

模板2:复杂查询构建步骤

-- 步骤1:确定目标列
SELECT 列1, 列2, 聚合函数

-- 步骤2:确定数据源
FROM 表A [别名], 表B [别名]

-- 步骤3:建立表间关联(n个表需要n-1个条件)
WHERE A.外键 = B.主键

-- 步骤4:行级筛选
AND 筛选条件

-- 步骤5:分组
GROUP BY 分组列

-- 步骤6:组级筛选
HAVING 组条件

-- 步骤7:排序
ORDER BY 排序列 [DESC];

三、存储过程与触发器

考点本质

存储过程考查封装业务逻辑的能力,触发器考查自动响应数据变化的能力。两者都是数据库编程的核心,区别在于:存储过程是"主动调用",触发器是"被动响应"。

3.1 核心知识体系

存储过程的本质:封装+复用+安全

特性
说明
考试体现
封装
将复杂操作封装为一个单元
多步操作写在一个过程中
复用
多次调用,一次编写
参数化设计
安全
通过参数控制访问
参数模式(IN/OUT/IN OUT)
性能
预编译,减少网络传输
游标批量处理

触发器的本质:事件驱动编程

要素
选项
选择依据
触发时机
BEFORE / AFTER
BEFORE用于校验,AFTER用于级联
触发事件
INSERT / DELETE / UPDATE
根据业务需求选择
触发粒度
FOR EACH ROW / STATEMENT
需要访问新旧值时用ROW
触发条件
WHEN 条件
进一步精确控制触发时机

NEW vs OLD 的本质

变量
含义
INSERT
DELETE
UPDATE
NEW
新记录
✓(插入的值)
✓(更新后的值)
OLD
旧记录
✓(删除的值)
✓(更新前的值)

3.2 考点深挖:存储过程的关键技术

深挖1:游标的本质与使用场景

本质:游标是逐行处理查询结果的机制,类似于编程语言中的迭代器。使用场景

  • 需要对查询结果的每一行进行不同处理
  • 不能用单条SQL完成的复杂逻辑

标准流程

DECLARE CURSOR 游标名 IS SELECT语句;  -- 声明:定义查询
OPEN 游标名;                           -- 打开:执行查询
FETCH 游标名 INTO 变量列表;            -- 取数据:逐行读取
-- 循环处理
CLOSE 游标名;                          -- 关闭:释放资源

考试陷阱

-- 错误:忘记判断游标结束
LOOP
    FETCH c INTO v;  -- 最后一次FETCH失败,v保留上一行值
    INSERT INTO ...; -- 会多插入一条重复记录
END LOOP;

-- 正确:先判断再处理
LOOP
    FETCH c INTO v;
    EXIT WHEN c%NOTFOUND;  -- 先判断
    INSERT INTO ...;       -- 再处理
END LOOP;

深挖2:事务控制的本质

本质:事务是保证数据一致性的边界。

BEGIN
    -- 操作1
    -- 操作2
    COMMIT;  -- 全部成功,永久生效
EXCEPTION WHEN OTHERS THEN
    ROLLBACK;  -- 任何失败,全部撤销
END;

考试重点

  • 必须有EXCEPTION WHEN OTHERS THEN ROLLBACK
  • COMMIT和ROLLBACK必须成对出现
  • FOR UPDATE用于加锁,防止并发修改

深挖3:参数模式的本质

模式
方向
用途
类比
IN
传入
输入数据
函数参数
OUT
传出
返回结果
返回值
IN OUT
双向
传入并修改
引用参数

深挖4:游标 vs 批量操作的对比

对比项
游标
批量操作
处理方式
逐行处理
一次性处理
性能
慢(逐行交互)
快(集合操作)
灵活性
高(每行可不同逻辑)
低(统一逻辑)
适用场景
每行处理逻辑不同
每行处理逻辑相同
考试频率

核心原则:能用批量操作就不用游标。考试中出现游标,通常是因为每行需要不同的处理逻辑。

深挖5:FOR UPDATE的本质

本质:在SELECT时加排他锁(X锁),防止其他事务同时修改。

SELECT ... INTO ... FROM 表 WHERE ... FOR UPDATE;

作用

  • 防止丢失更新
  • 确保读取的数据在事务结束前不被其他事务修改
  • 保证数据一致性

注意:FOR UPDATE只在事务中有效,事务提交或回滚后锁自动释放。

深挖6:存储过程中的异常处理

异常类型
处理方式
说明
NO_DATA_FOUND
游标未找到数据
游标FETCH失败
TOO_MANY_ROWS
SELECT INTO返回多行
预期单行但返回多行
OTHERS
其他所有异常
通用捕获

标准异常处理结构

BEGIN
    -- 业务逻辑
    COMMIT;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        -- 处理无数据情况
        ROLLBACK;
    WHEN TOO_MANY_ROWS THEN
        -- 处理多行情况
        ROLLBACK;
    WHEN OTHERS THEN
        -- 处理其他异常
        ROLLBACK;
END;

3.3 考点深挖:触发器的关键技术

深挖1:BEFORE vs AFTER 的选择

时机
能做什么
不能做什么
典型应用
BEFORE
修改NEW记录、校验数据
修改其他表
数据验证、默认值设置
AFTER
修改其他表、发送通知
修改NEW记录
级联操作、日志记录

本质原因:BEFORE时事务还未提交,修改其他表可能导致不一致;AFTER时当前操作已完成,可以安全地操作其他表。

深挖2:行级 vs 语句级触发器

粒度
触发次数
能否访问NEW/OLD
适用场景
FOR EACH ROW
每行一次
需要基于行数据做判断
FOR EACH STATEMENT
每次语句一次
不能
只需要知道发生了操作

考试重点:需要访问NEW.列名OLD.列名时,必须用FOR EACH ROW

深挖3:触发器中的条件判断

-- 只在库存从高于最低值变为低于最低值时触发
WHEN NEW.all_nums < (SELECT level FROM bookminlevel WHERE ...)
AND OLD.all_nums >= (SELECT level FROM bookminlevel WHERE ...)

本质:通过比较NEW和OLD,精确控制触发时机,避免不必要的触发。

深挖4:触发器与存储过程的对比

对比项
触发器
存储过程
调用方式
自动触发(被动)
显式调用(主动)
参数
无参数(使用NEW/OLD)
有IN/OUT/IN OUT参数
返回值
无返回值
可通过OUT参数返回值
事务控制
不能显式COMMIT/ROLLBACK
可以显式COMMIT/ROLLBACK
适用场景
数据变更的自动响应
复杂业务逻辑的封装

核心区别:触发器是"事件驱动",存储过程是"命令驱动"。

深挖5:触发器的执行顺序

当多个触发器作用于同一表时,执行顺序为:

BEFORE STATEMENT触发器
    → BEFORE ROW触发器(每行)
        → 执行DML操作
    → AFTER ROW触发器(每行)
→ AFTER STATEMENT触发器

考试要点

  • BEFORE触发器可以修改NEW的值
  • AFTER触发器不能修改NEW的值
  • 同一事件多个触发器,执行顺序不确定(依赖具体DBMS)

深挖6:触发器的限制与注意事项

限制
说明
考试陷阱
不能显式提交/回滚
触发器内不能写COMMIT/ROLLBACK
错误地在触发器内写COMMIT
不能修改触发表
行级触发器不能修改触发表本身
在AFTER UPDATE触发器中再次UPDATE本表
递归触发
触发器操作可能触发其他触发器
导致无限递归
性能影响
每次DML都执行触发器逻辑
大数据量操作时性能下降

记忆口诀:触发器三不能——不能提交、不能回滚、不能改本表(行级)。

3.4 举一反三:存储过程变式

变式1:带OUT参数的存储过程

CREATE PROCEDURE GetStats(
    IN deptId CHAR(10),
    OUT empCount INT,
    OUT avgSalary DECIMAL(10,2)
)
BEGIN
    SELECT COUNT(*), AVG(salary)
    INTO empCount, avgSalary
    FROM employees
    WHERE dept_id = deptId;
END;

变式2:动态SQL的存储过程

CREATE PROCEDURE DynamicQuery(IN tableName VARCHAR(50))
BEGIN
    -- 注意:实际考试中较少涉及,了解即可
    SET @sql = CONCAT('SELECT * FROM ', tableName);
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END;

3.5 举一反三:触发器变式

变式1:多事件触发器

CREATE TRIGGER AuditTrigger
AFTER INSERT OR UPDATE OR DELETE ON employees
FOR EACH ROW
BEGIN
    IF INSERTING THEN
        INSERT INTO audit_log VALUES ('INSERT', NEW.id, SYSDATE);
    ELSIF UPDATING THEN
        INSERT INTO audit_log VALUES ('UPDATE', NEW.id, SYSDATE);
    ELSIF DELETING THEN
        INSERT INTO audit_log VALUES ('DELETE', OLD.id, SYSDATE);
    END IF;
END;

变式2:级联删除触发器

CREATE TRIGGER CascadeDelete
BEFORE DELETE ON departments
FOR EACH ROW
BEGIN
    -- 删除部门前,先删除该部门的员工
    DELETE FROM employees WHERE dept_id = OLD.dept_id;
END;

3.6 真题映射(考点落地)

【2023年-工资计算系统】

  • 考点
    :存储过程(参数模式+SELECT INTO+事务控制)
  • 深挖
    FOR UPDATE的作用是在读取时加X锁,防止并发修改导致数据不一致。

【2022年-银行账务系统】

  • 考点
    :游标+批量插入
  • 深挖
    :游标适用于"逐行处理且每行逻辑不同"的场景。如果每行处理逻辑相同,可以用INSERT INTO SELECT批量完成。

【2021年-网上书城系统】

  • 考点
    :AFTER触发器+NEW/OLD+条件判断
  • 深挖
    WHEN NEW.all_nums < ... AND OLD.all_nums >= ...精确控制只在"库存从高于最低值变为低于最低值"时触发,避免重复触发。

3.7 答题模板

模板1:存储过程(带游标)

CREATE PROCEDURE 过程名(IN 参数 类型)
DECLARE
    变量1 类型;
    变量2 类型;
    CURSOR 游标名 IS SELECT语句;
BEGIN
    OPEN 游标名;
    LOOP
        FETCH 游标名 INTO 变量1, 变量2;
        EXIT WHEN 游标名%NOTFOUND;  -- 先判断结束
        -- 业务逻辑
    END LOOP;
    CLOSE 游标名;
    COMMIT;
EXCEPTION WHEN OTHERS THEN
    ROLLBACK;
END;

模板2:BEFORE触发器(数据验证)

CREATE TRIGGER 触发器名
BEFORE INSERT OR UPDATE ON 表名
FOR EACH ROW
BEGIN
    IF NEW.列 < 0 THEN
        Raise_Error;  -- 抛出异常,阻止操作
    END IF;
END;

模板3:AFTER触发器(级联操作)

CREATE TRIGGER 触发器名
AFTER INSERT OR DELETE OR UPDATE ON 表名
FOR EACH ROW
BEGIN
    IF INSERTING THEN
        UPDATE 另一表 SET 列 = 列 + 1 WHERE ...;
    ELSIF DELETING THEN
        UPDATE 另一表 SET 列 = 列 - 1 WHERE ...;
    END IF;
END;

四、事务并发控制

考点本质

事务并发控制考查的是多用户同时访问数据库时如何保证数据一致性的能力。核心在于理解并发操作导致的数据不一致性问题,以及如何通过封锁机制和隔离级别解决这些问题。

4.1 核心知识体系

事务的ACID本质

特性
英文
本质含义
实现机制
原子性
Atomicity
事务是不可分割的工作单位
Undo日志
一致性
Consistency
事务执行前后数据库处于一致状态
完整性约束
隔离性
Isolation
并发事务互不干扰
封锁机制
持久性
Durability
已提交的事务永久生效
Redo日志

并发问题的本质:操作的交错执行

核心思想:如果事务串行执行(一个做完再做另一个),不会出现问题。问题源于操作的交错执行

问题类型
本质
根本原因
形象比喻
丢失更新
后提交的覆盖先提交的
同时读取,先后写入
两人同时改同一文件,后保存的覆盖先保存的
脏读
读取了未提交的数据
读取了"脏"数据
看到别人未保存的草稿,并基于此做判断
不可重复读
同一事务内两次读取结果不同
其他事务修改并提交
读第一页时有人改了内容,再读时变了
幻读
同一事务内两次查询结果集不同
其他事务插入或删除
第一次查有10条,第二次查有11条

4.2 考点深挖:封锁机制

深挖1:S锁与X锁的本质

锁类型
英文
本质
兼容性
S锁
Shared Lock
"我要读,你们也可以读,但都不能写"
与S锁兼容,与X锁不兼容
X锁
Exclusive Lock
"我要写,你们既不能读也不能写"
与任何锁都不兼容

兼容性矩阵

请求S锁
请求X锁
已有S锁
✓ 兼容
✗ 不兼容
已有X锁
✗ 不兼容
✗ 不兼容

深挖2:封锁协议的层级

协议
规则
解决问题
本质
一级封锁
修改前加X锁,事务结束释放
丢失更新
写操作互斥
二级封锁
一级 + 读取前加S锁,读完释放
丢失更新、脏读
读写完释放
三级封锁
一级 + 读取前加S锁,事务结束释放
丢失更新、脏读、不可重复读
读写都保持到结束
两段锁2PL
扩展阶段只加锁,收缩阶段只解锁
保证可串行化
加锁和解锁分两个阶段

记忆口诀

一级改:只解决丢失更新
二级读:解决脏读(读完就放)
三级锁:解决不可重复读(事务结束才放)

深挖3:2PL协议与死锁

2PL协议的本质

  • 扩展阶段(Growing Phase):只能加锁,不能解锁
  • 收缩阶段(Shrinking Phase):只能解锁,不能加锁

2PL能保证什么

  • ✓ 保证并发调度的可串行性
  • ✗ 不保证不死锁

死锁的本质:循环等待

T1: XLock(A) → 请求 XLock(B) → 等待T2
T2: XLock(B) → 请求 XLock(A) → 等待T1
结果:死锁!

死锁解决方案

方案
本质
适用场景
预防
一次性加完所有锁
锁数量少且已知
顺序加锁
所有事务按相同顺序加锁
锁类型固定
检测
构建等待图,检测环
动态环境
超时
超过等待时间自动回滚
简单场景

4.3 考点深挖:隔离级别

隔离级别的本质:性能与一致性的权衡

隔离级别
丢失更新
脏读
不可重复读
幻读
本质
READ UNCOMMITTED
不加锁,性能最高
READ COMMITTED
读已提交,Oracle默认
REPEATABLE READ
可重复读,MySQL默认
SERIALIZABLE
完全串行,性能最低

关键理解

  • 隔离级别越高,一致性越好,但并发性能越差
  • 选择隔离级别需要在一致性和性能之间权衡

深挖4:隔离级别的实现机制

隔离级别
实现机制
S锁持有时间
特点
READ UNCOMMITTED
不加锁
不加S锁
直接读取最新值,可能脏读
READ COMMITTED
加S锁,读完释放
每次读都获取最新已提交值
REPEATABLE READ
加S锁,事务结束释放
事务内多次读取结果一致
SERIALIZABLE
加范围锁
事务结束释放
完全串行化,防止幻读

本质理解

  • READ COMMITTED:S锁只保护单次读取,不保护整个事务
  • REPEATABLE READ:S锁保护整个事务,防止其他事务修改已读数据
  • SERIALIZABLE:不仅保护已读数据,还防止新数据插入(幻读)

深挖5:MVCC(多版本并发控制)

本质:通过保存数据的多个版本,实现读写不阻塞。核心思想

  • 写操作创建新版本
  • 读操作读取旧版本
  • 不同事务看到不同版本

与封锁的对比

对比项
封锁机制
MVCC
读-写冲突
读等写,写等读
读不写等,写不读等
实现复杂度
简单
复杂
性能
冲突多时性能下降
读写并行性能好
适用场景
冲突少的场景
读多写少的场景

考试要点

  • MVCC解决的是读写冲突,不是写写冲突
  • 写写冲突仍需要X锁
  • MVCC不能解决丢失更新,需要配合其他机制

4.4 举一反三:并发场景分析

场景1:丢失更新(库存扣减)

T1: read(A)=100
T2: read(A)=100
T1: A=A-10=90, write(A)=90
T2: A=A-20=80, write(A)=80  -- T1的更新丢失!

正确结果:应该是 100 - 10 - 20 = 70实际结果:A = 80(T1的-10丢失了)解决方案

T1: XLock(A), read(A)=100, A=90, write(A), Unlock(A)
T2: XLock(A) -- 等待T1释放锁

场景2:脏读(转账回滚)

T1: read(A)=1000, A=900, write(A)=900
T2: read(A)=900  -- 脏读!T1还未提交
T1: ROLLBACK  -- A恢复为1000

结果:T2读取了不存在的数据900解决方案

T1: XLock(A), read(A), A=900, write(A)...
T2: SLock(A) -- 等待T1释放X锁

场景3:不可重复读(统计报表)

T1: read(A)=100
T2: read(A)=100, A=150, write(A)=150, COMMIT
T1: read(A)=150  -- 同一事务两次读取不同!

解决方案

T1: SLock(A), read(A)=100...
T2: XLock(A) -- 等待T1释放S锁

4.5 真题映射(考点落地)

【2023年-工资计算系统】

  • 考点
    :丢失更新
  • 深挖
    :工资计算事务和奖罚事务同时修改同一员工的工资记录,后提交的覆盖先提交的。2PL可以解决,但可能产生死锁。

【2021年-网上书城系统】

  • 考点
    :脏读
  • 深挖
    :用户1修改库存后回滚,用户2读取了未提交的修改并基于此计算,导致数据不一致。

【2022年-银行账务系统】

  • 考点
    :隔离级别+MVCC
  • 深挖
    :提交读隔离级别下,汇总事务读取已提交的数据;MVCC通过快照读避免读写冲突。

4.6 答题模板

模板1:并发问题分析

步骤1:画出时间线,列出每个事务的操作
步骤2:跟踪数据项的值变化
步骤3:判断是否存在以下情况:
       - 两个事务都读同一数据,然后先后写 → 丢失更新
       - 读取了未提交的数据 → 脏读
       - 同一事务内两次读取结果不同 → 不可重复读
       - 同一事务内两次查询记录数不同 → 幻读
步骤4:给出正确结果和实际结果,分析差异

模板2:并发问题解决方案

方案1:加锁(XLock/SLock)
方案2:提高隔离级别
方案3:使用MVCC(多版本并发控制)
方案4:乐观并发控制(提交时检查冲突)

五、数据库故障恢复

考点本质

数据库故障恢复考查的是在系统发生故障后如何保证数据一致性和持久性的能力。核心在于理解日志机制、检查点技术和Redo/Undo恢复算法。

5.1 核心知识体系

故障类型的本质区别

故障类型
影响范围
恢复方式
本质
事务故障
单个事务
Undo
事务执行错误
系统故障
所有活跃事务
Redo + Undo
内存数据丢失
介质故障
整个数据库
备份 + 日志恢复
磁盘数据丢失

日志的本质:数据库的"黑匣子"

日志记录了所有对数据库的修改操作,是恢复的唯一依据

日志格式
含义
恢复作用
<Ti, START>
事务Ti开始
标记事务起点
<Ti, COMMIT>
事务Ti提交
标记事务已提交,需Redo
<Ti, D, V1, V2>
Ti将D从V1改为V2
Redo: D=V2, Undo: D=V1
<Ti, abort>
事务Ti回滚结束
标记事务已撤销
CHECKPOINT
检查点
减少恢复扫描范围

5.2 考点深挖:检查点恢复算法

深挖1:检查点的本质

本质:检查点是数据库的一个一致性快照点,用于减少恢复时需要扫描的日志量。检查点的工作

  1. 暂停所有事务
  2. 将内存中的修改刷新到磁盘
  3. 写入CHECKPOINT日志记录
  4. 恢复事务执行

深挖2:Redo/Undo的本质

操作
方向
对象
本质
Redo
正向扫描(从旧到新)
已提交事务
保证持久性(已提交的修改不丢失)
Undo
反向扫描(从新到旧)
未提交事务
保证原子性(未提交的修改不保留)

为什么Redo正向,Undo反向?

  • Redo正向:一个数据项可能被多个事务修改,正向扫描保证最终值是最后一个已提交事务的值
  • Undo反向:一个未提交事务可能修改了多个数据项,反向扫描保证按修改的逆序撤销

深挖3:WAL原则(Write Ahead Logging)

本质:先写日志,后写数据库。为什么必须先写日志?

错误顺序(先写数据库):
  1. T1修改A: A=100→200(写入数据库)
  2. 系统崩溃(日志未写入)
  3. 恢复时:没有T1的日志记录
  4. 结果:T1的修改永久生效(即使T1未提交)

正确顺序(先写日志):
  1. T1写入日志: <T1,A,100,200>
  2. T1修改A: A=100→200(写入数据库)
  3. 系统崩溃
  4. 恢复时:根据日志Redo/Undo

深挖4:检查点的分类与对比

检查点类型
特点
优点
缺点
模糊检查点
不强制刷盘,只记录日志
不影响事务执行
恢复时需要扫描更多日志
sharp检查点
强制刷盘,暂停事务
恢复时扫描日志少
影响性能,有停顿
非静止检查点
允许事务继续执行
性能影响小
实现复杂

考试重点:模糊检查点是最常用的,恢复时需要Redo检查点后已提交的事务。

深挖5:日志记录格式的本质

日志类型
格式
恢复操作
适用场景
物理日志<Ti, 页号, 偏移量, 旧值, 新值>
直接修改磁盘页
低层恢复,效率高
逻辑日志<Ti, SQL语句>
重新执行SQL
高层恢复,灵活
物理逻辑日志<Ti, 记录标识, 旧值, 新值>
修改特定记录
平衡效率和灵活性

考试要点

  • 物理日志:Undo简单(直接写旧值),但日志量大
  • 逻辑日志:日志量小,但Undo复杂(需要逆操作)
  • 物理逻辑日志:折中方案,最常用

深挖6:ARIES恢复算法(进阶)

核心思想

  • Analysis阶段
    :分析日志,确定Redo/Undo范围
  • Redo阶段
    :重做所有已提交事务(包括检查点前的)
  • Undo阶段
    :撤销所有未提交事务

与简单恢复算法的区别

  • ARIES使用LSN(日志序列号)链
  • 支持模糊检查点
  • 支持嵌套事务

考试要点:了解ARIES的三个阶段即可,不需要深入细节。

深挖7:备份策略的本质

备份类型
本质
恢复时间
空间占用
全量备份
备份整个数据库
增量备份
备份自上次备份后的修改
差异备份
备份自上次全量备份后的修改

备份策略选择

  • 全量+增量:适合修改少的场景
  • 全量+差异:适合修改多的场景
  • 全量+日志:最常用,适合大多数场景

5.3 举一反三:恢复场景分析

场景1:系统故障恢复

日志

LSN1: <T1, START>
LSN2: <T1, A, 10, 20>
LSN3: <T2, START>
LSN4: <T2, B, 30, 40>
LSN5: <T1, COMMIT>
LSN6: CHECKPOINT
LSN7: <T2, A, 20, 50>
LSN8: <T3, START>
LSN9: <T3, B, 40, 60>
LSN10: CRASH

分析

事务
状态
操作
T1
已提交
Redo
T2
未提交
Undo
T3
未提交
Undo

Redo(正向)

  • LSN2: A = 10 → 20

Undo(反向)

  • LSN9: B = 60 → 40
  • LSN7: A = 50 → 20
  • LSN4: B = 40 → 30

结果:A = 20, B = 30

场景2:介质故障恢复

恢复步骤

  1. 修复或更换损坏磁盘
  2. 重装数据库管理系统
  3. 载入最近的数据库备份
  4. 利用日志恢复:
  • Redo:重做备份后已提交的事务
  • Undo:撤销备份后未提交的事务

5. 验证数据一致性与系统故障的区别

故障类型
恢复方式
是否需要备份
系统故障
日志恢复
介质故障
备份+日志恢复

5.4 真题映射(考点落地)

【2022年-数据库故障恢复】

  • 考点
    :检查点+Redo/Undo
  • 深挖
    :CHECKPOINT前已提交的事务(T1)也需要Redo,因为检查点时不保证所有修改都已刷盘。

【2020年-数据库故障恢复】

  • 考点
    :WAL原则
  • 深挖
    :如果先写数据库再记日志,已提交的事务可能因为COMMIT日志未写入而被错误地Undo。

5.5 答题模板

模板1:恢复过程分析

步骤1:从事务状态判断Redo/Undo列表
       - 有COMMIT → Redo
       - 无COMMIT → Undo

步骤2:Redo阶段(正向扫描)
       - 从CHECKPOINT开始正向扫描
       - 对已提交事务,按日志顺序重做修改

步骤3:Undo阶段(反向扫描)
       - 从CRASH点反向扫描
       - 对未提交事务,按逆序撤销修改

步骤4:计算最终结果
       - 初始值 + 已提交修改 - 未提交修改

模板2:介质故障恢复

1. 修复硬件(更换磁盘)
2. 重装DBMS
3. 载入最近备份
4. 扫描日志:
   - Redo:备份后已提交的事务
   - Undo:备份后未提交的事务
5. 验证一致性

六、范式与关系模式规范化

考点本质

范式考查的是如何设计没有数据冗余和异常的关系模式。核心在于理解函数依赖、识别冗余来源,并掌握模式分解的方法。

6.1 核心知识体系

函数依赖的本质:属性间的决定关系

概念
定义
本质
判断方法
函数依赖
X→Y:X确定则Y确定
Y对X的依赖关系
看X相同则Y是否一定相同
完全依赖
Y依赖于整个X
X的任意真子集都不能决定Y
去掉X的任一属性,依赖是否还成立
部分依赖
Y只依赖于X的一部分
X的某个真子集就能决定Y
找到X的真子集能决定Y
传递依赖
X→Y, Y→Z,则X→Z
通过中间属性传递
找到中间属性Y

范式的本质:逐步消除冗余

范式
要求
消除的冗余
本质
1NF
属性不可再分
重复组、多值属性
最基本的结构化
2NF
1NF + 消除部分依赖
非主属性对主键的部分依赖
每个非主属性都完全依赖主键
3NF
2NF + 消除传递依赖
非主属性对主键的传递依赖
非主属性直接依赖主键
BCNF
每个决定因素都是候选键
主属性对候选键的依赖
更强的3NF
4NF
消除多值依赖
非平凡多值依赖
处理多值属性

递进关系

1NF ⊃ 2NF ⊃ 3NF ⊃ BCNF ⊃ 4NF
(越往后约束越强,冗余越少)

6.2 考点深挖:模式分解

深挖1:分解的目标

核心目标

  1. 无损连接性
    :分解后能通过自然连接恢复原始关系
  2. 保持函数依赖
    :分解后仍能表达原有的所有函数依赖

考试重点:通常要求分解到3NF或BCNF,且保持函数依赖。

深挖2:部分依赖的分解

识别:非主属性只依赖于主键的一部分。分解方法:将部分依赖的属性分离成新表。示例

原表:选课(学号,课程号,姓名,成绩)
      主键:(学号,课程号)
      部分依赖:学号 → 姓名

分解:
1. 选课(学号,课程号,成绩)
2. 学生(学号,姓名)

深挖3:传递依赖的分解

识别:非主属性通过另一个非主属性依赖于主键。分解方法:将传递依赖的中间属性分离成新表。示例

原表:学生(学号,姓名,系号,系主任)
      传递依赖:学号 → 系号 → 系主任

分解:
1. 学生(学号,姓名,系号)
2. 系(系号,系主任)

深挖4:多值依赖与4NF

本质:一个属性值对应另一组属性的多个值,且这两组属性互相独立。识别

病例(编号,药品条码,患者,医生,病情,诊断,日期,剂量,数量)
      编号 →→ 药品, 剂量, 数量(多值依赖)

分解

1. 病例基本信息(编号,患者,医生,病情,诊断,日期)
2. 病例药品信息(编号,药品条码,剂量,数量)

深挖5:候选键的求解方法

本质:候选键是能唯一确定所有属性的最小属性集。求解步骤

  1. 找L类属性
    :只出现在函数依赖左边的属性(一定属于候选键)
  2. 找R类属性
    :只出现在函数依赖右边的属性(一定不属于候选键)
  3. 找LR类属性
    :两边都出现的属性(可能属于候选键)
  4. 找N类属性
    :两边都没出现的属性(一定属于候选键)

判断方法

  • 如果L类和N类属性的闭包包含所有属性 → 这就是候选键
  • 如果不包含,逐个加入LR类属性,直到闭包包含所有属性

示例

关系R(A, B, C, D, E)
函数依赖:A→B, B→C, C→D, D→E

分析:
- L类:A
- R类:E
- LR类:B, C, D
- N类:无

A的闭包:A → B → C → D → E
包含所有属性,所以候选键是{A}

深挖6:无损连接性的判断

本质:分解后能通过自然连接恢复原始关系。判断方法(表格法)

  1. 构造一个表格,行是分解后的关系模式,列是原始关系的所有属性
  2. 如果某关系模式包含某属性,填a;否则填b
  3. 根据函数依赖,逐步修改表格
  4. 如果某一行全为a,则分解是无损的

示例

R(A, B, C), F = {A→B}
分解为:R1(A, B), R2(A, C)

表格:
      A  B  C
R1    a  a  b
R2    a  b  a

根据A→B:R1和R2的A都是a,所以R2的B应该等于R1的B
修改后:
      A  B  C
R1    a  a  b
R2    a  a  a  ← 全为a,无损!

深挖7:函数依赖保持性的判断

本质:分解后的每个函数依赖都能在某一个分解后的关系模式上验证。判断方法

  1. 对每个函数依赖X→Y,检查X和Y是否都在同一个分解后的关系模式中
  2. 如果都在,则该函数依赖被保持
  3. 如果所有函数依赖都被保持,则分解保持函数依赖

注意:无损连接性和函数依赖保持性是独立的,一个分解可以无损但不保持函数依赖,也可以保持函数依赖但有损。

深挖8:BCNF vs 3NF的选择

对比项
3NF
BCNF
要求
消除传递依赖
每个决定因素都是候选键
函数依赖保持
可以保持
可能不保持
无损连接
可以保持
一定保持
实际应用
常用
理论完美但可能不保持依赖

选择原则

  • 如果需要保持函数依赖 → 选择3NF
  • 如果可以接受不保持函数依赖 → 选择BCNF
  • 实际应用中,3NF通常是最佳选择

6.3 举一反三:范式判断练习

练习1:判断2NF

关系:选课(学号,课程号,姓名,课程名,成绩)
主键:(学号,课程号)

分析:
- 学号 → 姓名(部分依赖)
- 课程号 → 课程名(部分依赖)

结论:不满足2NF

练习2:判断3NF

关系:学生(学号,姓名,系号,系主任)
主键:学号

分析:
- 学号 → 系号(直接依赖)
- 系号 → 系主任(传递依赖)
- 学号 → 系主任(传递依赖)

结论:不满足3NF

练习3:判断BCNF

关系:选课(学生,课程,教师)
假设:每个教师只教一门课,一门课有多个教师
函数依赖:
- (学生,课程)→ 教师
- 教师 → 课程

分析:
- 候选键:(学生,课程)、(学生,教师)
- 教师 → 课程:决定因素"教师"不是候选键

结论:不满足BCNF

6.4 真题映射(考点落地)

【2023年-维修配件管理系统】

  • 考点
    :BCNF分解
  • 深挖
    :识别出配件编码→配件名称、配件编码→配件供应商等依赖,配件编码不是超键,所以不满足BCNF。

【2019年-快递跟踪管理系统】

  • 考点
    :3NF判断+传递依赖分解
  • 深挖
    :快递编号→发件人身份证号→发件人姓名/电话/地址,存在传递依赖,分解为两个关系。

【2018年-医院信息管理系统】

  • 考点
    :4NF+多值依赖
  • 深挖
    :病例编号→→药品/剂量/数量是多值依赖,一个病例对应多个药品,且药品之间互相独立。

6.5 答题模板

模板1:范式判断

步骤1:确定候选键(能唯一确定所有属性的最小属性集)
步骤2:找出所有函数依赖
步骤3:判断是否满足各范式:
       - 1NF:属性是否可再分?
       - 2NF:是否存在部分依赖?
       - 3NF:是否存在传递依赖?
       - BCNF:每个决定因素是否都是候选键?
步骤4:如不满足,说明理由

模板2:模式分解

步骤1:找出违反范式的函数依赖
步骤2:将违反依赖的属性分离成新表
步骤3:确保分解后的每个关系都满足目标范式
步骤4:标注主键(下划线)和外键(→参照)
步骤5:验证无损连接性和函数依赖保持性

模板3:数据异常分析

插入异常:
- 问题:无法插入某些信息
- 原因:缺少主键的一部分

删除异常:
- 问题:删除某条记录时丢失其他信息
- 原因:不同实体的信息混在一起

修改异常:
- 问题:修改某属性时需要修改多条记录
- 原因:数据冗余

附录:案例题答题通用技巧

技巧1:审题三步法

第一步:读说明,识别实体、属性、联系
第二步:读问题,明确考查的知识点
第三步:回看说明,提取解题所需信息

技巧2:E-R图题答题要点

1. 实体用矩形,属性用椭圆,联系用菱形
2. 联系类型标注在连线旁(1:1、1:n、n:m)
3. n:m联系必须单独成表
4. 联系属性属于联系,不属于实体

技巧3:SQL题答题要点

1. CREATE TABLE:先主键,再外键,最后其他约束
2. 多表连接:n个表需要n-1个连接条件
3. 分组统计:SELECT中的非聚合列必须出现在GROUP BY中
4. 子查询:NOT IN用于"不在...中",EXISTS用于"存在..."

技巧4:存储过程/触发器题答题要点

1. 存储过程:参数模式(IN/OUT)、游标(声明-打开-取数据-关闭)、事务控制(COMMIT/ROLLBACK)
2. 触发器:BEFORE/AFTER、INSERT/UPDATE/DELETE、FOR EACH ROW、NEW/OLD
3. 注意语法细节:分号、END IF、LOOP/EXIT

技巧5:并发控制题答题要点

1. 画出时间线表格
2. 跟踪每个事务的变量值和数据库值
3. 判断问题类型:丢失更新/脏读/不可重复读/幻读
4. 解决方案:加锁(XLock/SLock)、提高隔离级别

技巧6:故障恢复题答题要点

1. 事务状态:有COMMIT→Redo,无COMMIT→Undo
2. Redo正向扫描,Undo反向扫描
3. 注意多个事务修改同一数据项的情况
4. 检查点减少恢复扫描范围

技巧7:范式题答题要点

1. 先找候选键
2. 再找函数依赖
3. 判断违反哪个范式
4. 分解时保持函数依赖和无损连接
5. 标注主键和外键

复习建议
:不要死记硬背真题答案,要理解每个考点背后的原理。通过"考点本质→深挖细节→举一反三→真题映射"的学习路径,建立完整的知识体系,才能在考试中灵活应对各种变式题目。

复习建议

理解考点本质 > 死记硬背真题
通过"考点本质→深挖细节→举一反三→真题映射"的学习路径,建立完整的知识体系

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-14 04:55:20 HTTP/2.0 GET : https://i.67808.cn/a/466562.html
  2. 运行时间 : 0.140675s [ 吞吐率:7.11req/s ] 内存消耗:5,034.50kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=cc2accbf74249def2a3c6cf43f344fc5
  1. /yingpanguazai/ssd/ssd1/www/i.67808.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/i.67808.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/i.67808.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/i.67808.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/i.67808.cn/runtime/temp/21b433f16374cbe8b5fe06f82f71202c.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/i.67808.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000556s ] mysql:host=127.0.0.1;port=3306;dbname=i_67808;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001597s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.003457s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000714s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001359s ]
  6. SELECT * FROM `set` [ RunTime:0.000614s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001811s ]
  8. SELECT * FROM `article` WHERE `id` = 466562 LIMIT 1 [ RunTime:0.001380s ]
  9. UPDATE `article` SET `lasttime` = 1778705720 WHERE `id` = 466562 [ RunTime:0.025050s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000761s ]
  11. SELECT * FROM `article` WHERE `id` < 466562 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001270s ]
  12. SELECT * FROM `article` WHERE `id` > 466562 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002730s ]
  13. SELECT * FROM `article` WHERE `id` < 466562 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002195s ]
  14. SELECT * FROM `article` WHERE `id` < 466562 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.003605s ]
  15. SELECT * FROM `article` WHERE `id` < 466562 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.003427s ]
0.144338s