2025-05-16-数据库-知识点整理

题目答案:

11-12题
11
(1)ALTER TABLE STUDENT ADD NATION VARCHAR2(20);
(2)ALTER TABLE STUDENT DROP COLUMN NATION;
(3)INSERT INTO GRADE VALUES ('2021110','3','80');
(4)UPDATE GRADE SET GMARK='70' WHERE SNO='2021110';
(5)DELETE FROM GRADE WHERE SNO='2021110';
(6)CREATE INDEX IX_CLASS ON GRADE(CNO ASC);
(7)DROP INDEX IX_CLASS;






12
(1)SELECT DISTINCT CNO FROM GRADE;
(2)SELECT * FROM STUDENT T WHERE T.SsEX='女' AND T.CLNO='20311';
(3)SELECT T.SNAME,T.SSEX,T.SBIRTH FROM STUDENT T WHERE T.CLNO='20311' OR T.CLNO='20312';
(4)SELECT * FROM STUDENT T WHERE T.SNAME LIKE '李%';
(5)SELECT COUNT(*)
FROM STUDENT S
WHERE S.CLNO=(SELECT CLNO FROM STUDENT WHERE SNAME="李勇")
(6)SELECT
MAX(GMARK) AS 最高分,
MIN(GMARK) AS 最低分,
AVG(GMARK) AS 平均分
FROM GRADE
WHERE CNO = (SELECT CNO FROM COURSE WHERE CNAME = '操作系统');
(7)SELECT COUNT(DISTINCT SNO)
FROM GRADE;
(8)SELECT COUNT(DISTINCT SNO)
FROM GRADE WHERE CNO=(SELECT CNO FROM COURSE WHERE CNAME='操作系统');
(9)
SELECT S.SNAME
FROM STUDENT S LEFT JOIN CLASS C ON S.CLNO=C.CLNO LEFT JOIN GRADE G ON S.SNO=G.SNO
WHERE C.INYEAR='2020' AND C.SPECIAL='计算机科学与技术' AND G.GMARK IS NULL;


(10)
SELECT C1.CNAME, C2.CNAME
    FROM COURSE C1,COURSE C2
        WHERE C2.CNO=C1.CPNO OR C1.CPNO IS NULL;
13
(1)
SELECT *
    FROM STUDENT S
        WHERE S.CLNO=(SELECT T.CLNO
                      FROM STUDENT T
                          WHERE T.SNAME='李勇'
                          );
(2)
SELECT S.*
    FROM STUDENT S,GRADE G
        WHERE S.SNO=G.SNO
            AND G.CNO IN (SELECT G2.CNO
                         FROM GRADE G2,STUDENT S2
                             WHERE G2.SNO=S2.SNO
                             AND S2.SNAME='李勇');
(3)
SELECT *
    FROM STUDENT S
        WHERE S.SBIRTH BETWEEN (SELECT S.SBIRTH
                                FROM STUDENT S2
                                WHERE S2.SNAME='李勇')
            AND to_date('2005-01-01','yyyy-mm-dd');
(4)
SELECT S.SNO,S.SNAME
    FROM STUDENT S,COURSE C,GRADE G
        WHERE C.CNAME='操作系统'
        AND C.CNO=G.CNO
        AND S.SNO=G.SNO;
(5)
SELECT S.SNAME
FROM STUDENT S
WHERE NOT EXISTS (
    SELECT 1
    FROM GRADE G
    WHERE G.SNO = S.SNO AND G.CNO = '1'
);
(6)
SELECT G1.SNO, G1.CNO
FROM GRADE G1
WHERE G1.GMARK > (
    SELECT AVG(G2.GMARK)
    FROM GRADE G2
    WHERE G2.SNO = G1.SNO
);
(7)
SELECT S.SNAME
FROM STUDENT S
WHERE NOT EXISTS (
    SELECT C.CNO
    FROM COURSE C
    WHERE NOT EXISTS (
        SELECT G.CNO
        FROM GRADE G
        WHERE G.SNO = S.SNO AND G.CNO = C.CNO
    )
);
14
(1)

15
(1)

16
(1)

数据库知识整理


一、SQL 查询基础

1. 嵌套子查询

  • 使用 IN 关键字
    外层查询依赖内层查询结果,内层查询先执行,结果传递给外层。
  • SELECT a.eno, a.ename
    FROM employee a, department b
    WHERE a.dno = b.dno
      AND b.dname = '技术科';
  • 相关子查询与 EXISTS
    外层逐条遍历,内层根据外层值动态执行。
  • — 示例:查询存在员工的部门
    SELECT dname
    FROM department d
    WHERE EXISTS (
        SELECT 1
        FROM employee e
        WHERE e.dno = d.dno
    );

2. 视图操作

  • 创建或替换视图
  • CREATE OR REPLACE VIEW v AS
    SELECT …; — 视图定义查询

二、数据库设计理论

1. 关系模式评估标准

  • 问题判断
    • 数据冗余程度(如重复存储姓名)
    • 增删改异常(如删除最后一个课程记录导致学生信息丢失)
  • 关系模式表示
    R(U, D, DOM, F)
    • U:属性集合(如学号、姓名)
    • D:域(数据类型,如 VARCHAR(10))
    • DOM:属性到域的映射
    • F:函数依赖(如学号 → 姓名)

2. 函数依赖

类型定义示例说明
完全函数依赖多属性组合决定另一属性,缺一不可(学号, 课程号) → 成绩成绩需学号和课程号共同确定
部分函数依赖主键中部分属性即可决定非主属性(学号, 课程号) → 姓名(学号可单独决定姓名)导致数据冗余
平凡函数依赖右侧属性包含在左侧集合中(学号, 姓名) → 学号永远成立,无实际意义
非平凡函数依赖右侧属性不全在左侧学号 → 姓名提供有效信息

3. 码(Key)与属性

  • 候选码:能唯一标识记录的最小属性集(如学号、身份证号)
  • 主码:从候选码中选定的核心标识(如学号)
  • 主属性:属于任一候选码的属性(如学号、身份证号)
  • 非主属性:不包含在候选码中的属性(如姓名、年龄)

类比

  • 候选码 = 多个候选人
  • 主码 = 当选总统
  • 主属性 = 候选人成员
  • 非主属性 = 普通群众

三、数据完整性

1. 完整性类型

类型实现方式示例
域完整性CHECK, DEFAULT性别只能是男/女
实体完整性PRIMARY KEY学号不能为空且唯一
参照完整性FOREIGN KEY外键关联主表主键
用户定义触发器、业务规则教授工资 ≥ 1000 元

2. 外键约束处理

  • 违约操作
    • NO ACTION(默认):拒绝操作
    • CASCADE:级联删除/更新
    • SET NULL/SET DEFAULT:设为空或默认值
  • ALTER TABLE Employee
    ADD CONSTRAINT fk_dept
    FOREIGN KEY (Dno) REFERENCES Department(Dno)
    ON DELETE CASCADE;

四、数据库安全性

  • 核心目标:防止非法访问
  • 实现手段
    • 权限管理:GRANT, REVOKE
    • 视图机制:隐藏敏感数据(如薪资)
    • 审计追踪:记录操作日志

与完整性的区别

  • 完整性防误操作(如无效数据)
  • 安全性防非法访问(如黑客入侵)

五、并发控制与恢复

1. 并发问题

  • 丢失更新、脏读、不可重复读、幻读
  • 解决机制
    • 事务(BEGIN, COMMIT, ROLLBACK)
    • 锁(行锁、表锁)
    • ACID 特性(原子性、一致性、隔离性、持久性)

2. 数据恢复

  • 日志:记录变更(UNDO/REDO)
  • 检查点(Checkpoint:定期保存状态
  • 恢复操作
    • UNDO:回滚未提交事务
    • REDO:重做已提交事务

六、触发器(Trigger

  • 作用:自动执行特定操作(如数据校验、级联更新)
  • 示例
  • CREATE TRIGGER trg_check_grade
    BEFORE INSERT ON SC
    FOR EACH ROW
    BEGIN
        IF NEW.grade < 0 OR NEW.grade > 100 THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '成绩必须在0~100之间';
        END IF;
    END;

##

概念核心区别
完全依赖 vs 部分依赖是否需要全部主键属性
平凡依赖 vs 非平凡依赖右侧是否在左侧存在
安全性 vs 完整性防非法访问 vs 防误操作

重点理解

  1. 主键与外键维护数据一致性
  2. 函数依赖影响数据库范式设计(如消除部分依赖)
  3. 事务与锁保障并发安全
  4. 视图与触发器增强数据管理灵活性

用生活中的例子讲清楚数据库范式


第一范式(1NF):字段不能再拆分

通俗理解
每一列的值都必须是「最小单元」,不能拆成更小的部分。
反例

学号地址(省、市、区合并)
001广东省深圳市南山区

问题:无法单独查询“深圳市的所有学生”。
解决:拆分成独立字段

学号
001广东深圳南山

第二范式(2NF):消除「部分依赖」

前提:先满足1NF。
通俗理解
如果主键是多个属性组合(比如学号+课程号),那么所有非主键字段必须依赖整个主键,而不是其中一部分。
反例

学号课程号姓名成绩
001C1张三90
  • 主键是(学号+课程号)
  • 姓名只依赖学号 → 部分依赖(冗余!)

解决:拆表

学生表(学号, 姓名) 
选课表(学号, 课程号, 成绩)


第三范式(3NF):消除「传递依赖」

前提:先满足2NF。
通俗理解
非主键字段之间不能互相依赖,只能直接依赖主键。
反例

学号班级班主任
001一班王老师
  • 班主任依赖班级 → 班级传递依赖学号 → 更新异常(换班主任要改多行)

解决:拆表

学生表(学号, 班级) 
班级表(班级, 班主任)


BC范式(BCNF):所有决定因素都是候选键

通俗理解
任何能决定其他字段的属性,必须是候选键(唯一标识记录的字段)。
反例
仓库管理表(仓库ID, 物品ID, 数量, 管理员)

  • 仓库ID + 物品ID → 数量
  • 管理员 → 仓库ID(一个管理员只管一个仓库)

问题

  • 管理员不是候选键,却能决定仓库ID → 违反BCNF

解决:拆表

库存表(仓库ID, 物品ID, 数量) 
仓库管理员表(仓库ID, 管理员)


总结对比表

范式核心要求解决问题生活类比
1NF字段不可再分数据结构混乱把地址拆成省市区
2NF消除部分依赖数据冗余学生姓名不依赖课程号
3NF消除传递依赖更新异常班主任不依赖学号,依赖班级
BCNF所有决定因素是候选键复杂依赖冲突管理员必须和仓库绑定

一句话总结

  • 1NF:字段不能再拆
  • 2NF:主键整体决定其他字段
  • 3NF:非主键之间不能互相依赖
  • BCNF:谁决定别人,谁就必须是候选键

实际意义
范式越高,数据冗余越少,更新越安全,但查询可能越复杂。实际设计时通常做到3NF即可!