1. 数据库系统基础概念解析
数据是数据库中最基本的组成单元,简单理解就是描述事物的符号记录。比如学生的学号"2023001"是一个数据,但只有结合"学号"这个语义,这个数字才有实际意义。数据可以表现为多种形式:文本、数字、图像、音频等。
**数据库(DB)**本质上是一个电子化的文件柜,比如学校使用的学生信息数据库,它长期存储在计算机中,具有以下特征:
- 结构化存储:数据按固定格式组织,比如学生记录包含学号、姓名、专业等固定字段
- 低冗余:相同数据不会重复存储在不同位置
- 高共享性:教务系统和财务系统可以同时访问学生数据
**数据库管理系统(DBMS)**相当于数据库的"管理员",常见的有MySQL、Oracle等。它的核心功能包括:
- 数据定义:通过DDL语言创建表结构
- 数据操作:支持增删改查等SQL操作
- 事务管理:保证转账等操作的完整性
- 权限控制:限制不同用户的访问范围
**数据库系统(DBS)**是一个完整生态,包含:
- 硬件:服务器、存储设备
- 软件:DBMS、应用程序
- 人员:DBA、开发人员、最终用户
提示:数据独立性是数据库系统的关键特性,包括物理独立性(存储结构变化不影响应用)和逻辑独立性(表结构变化有限影响应用),这通过三级模式结构实现。
2. 关系数据库核心原理
2.1 关系模型三要素
关系数据库采用二维表结构,其核心包含:
数据结构:由行列组成的二维表,例如学生表:
+-------+-------+------+ | Sno | Sname | Sage | +-------+-------+------+ | 2023001 | 张三 | 20 | | 2023002 | 李四 | 21 | +-------+-------+------+完整性约束:
- 实体完整性:主键(如Sno)非空且唯一
- 参照完整性:外键必须引用存在的值
- 用户定义完整性:如年龄必须大于0
关系操作:基于关系代数,包括:
- 选择(σ):筛选满足条件的行
- 投影(π):选择特定列
- 连接(⋈):合并多个表的关联数据
2.2 关系代数实战
假设有学生表Student和选课表SC:
-- 查询计算机系的学生(选择操作) σ_Sdept='CS'(Student) -- 查询学生姓名和年龄(投影操作) π_Sname,Sage(Student) -- 查询选修了1号课程的学生姓名(连接+投影) π_Sname(Student ⋈ σ_Cno='1'(SC))实际SQL实现:
-- 对应上述关系代数的SQL语句 SELECT Sname FROM Student WHERE Sdept='CS'; SELECT Sname, Sage FROM Student; SELECT Sname FROM Student NATURAL JOIN SC WHERE Cno='1';3. SQL语言深度应用
3.1 数据库定义
创建学生表的SQL示例:
CREATE TABLE Student ( Sno CHAR(9) PRIMARY KEY, -- 学号作为主键 Sname VARCHAR(20) UNIQUE, -- 姓名唯一 Ssex CHAR(2), Sage INT CHECK(Sage>0), -- 年龄必须大于0 Sdept VARCHAR(20) );索引的创建与使用:
-- 在Sname上创建索引加速查询 CREATE INDEX Idx_Sname ON Student(Sname); -- 索引使用示例(数据库自动选择) SELECT * FROM Student WHERE Sname='张三';3.2 复杂查询技巧
多表连接查询:
-- 查询选修'数据库'课程的学生名单 SELECT S.Sname FROM Student S, SC, Course C WHERE S.Sno=SC.Sno AND SC.Cno=C.Cno AND C.Cname='数据库';聚合函数与分组:
-- 统计各系学生平均年龄 SELECT Sdept, AVG(Sage) AS AvgAge FROM Student GROUP BY Sdept HAVING AVG(Sage) > 20; -- 筛选平均年龄>20的系4. 数据库设计与规范化
4.1 E-R模型设计
设计学生选课系统的E-R模型:
- 实体:学生(学号,姓名)、课程(课程号,名称)
- 联系:选课(成绩,学期)
- 属性:学生实体的年龄、性别等
转换关系模式:
- 学生(学号,姓名,年龄,性别)
- 课程(课程号,名称,学分)
- 选课(学号,课程号,成绩,学期)
4.2 范式化实战
原始表R(学号,课程号,成绩,姓名,系名)存在问题:
- 数据冗余:同一学生选修多门课会导致姓名重复存储
- 更新异常:修改学生姓名需更新多条记录
- 删除异常:删除某学生选课可能丢失学生信息
规范化过程:
- 1NF:已满足(所有属性不可再分)
- 2NF:消除部分依赖
- 选课(学号,课程号,成绩)
- 学生(学号,姓名,系名)
- 3NF:消除传递依赖
- 学生(学号,姓名,系编号)
- 院系(系编号,系名)
5. 事务管理与并发控制
5.1 事务特性(ACID)
银行转账示例:
BEGIN TRANSACTION; UPDATE Accounts SET balance=balance-100 WHERE id=1; UPDATE Accounts SET balance=balance+100 WHERE id=2; COMMIT;- 原子性:要么全部执行,要么全部回滚
- 一致性:转账前后总金额不变
- 隔离性:其他事务看不到中间状态
- 持久性:提交后结果永久保存
5.2 并发问题解决方案
常见并发问题:
- 丢失更新:两个事务同时修改同一数据
- 脏读:读到未提交的数据
- 不可重复读:同一事务内多次读取结果不同
解决方案:
-- 设置隔离级别 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- 使用悲观锁 SELECT * FROM Accounts WHERE id=1 FOR UPDATE;6. 学生选课系统实战
6.1 数据库构建
完整建表语句:
-- 院系表 CREATE TABLE Department ( Dno CHAR(2) PRIMARY KEY, Dname VARCHAR(20) UNIQUE ); -- 学生表 CREATE TABLE Student ( Sno CHAR(9) PRIMARY KEY, Sname VARCHAR(20) NOT NULL, Ssex CHAR(1) CHECK(Ssex IN('M','F')), Sage INT CHECK(Sage>=15 AND Sage<=45), Dno CHAR(2), FOREIGN KEY (Dno) REFERENCES Department(Dno) ); -- 课程表 CREATE TABLE Course ( Cno CHAR(4) PRIMARY KEY, Cname VARCHAR(40) NOT NULL, Credit INT CHECK(Credit>0) ); -- 选课表 CREATE TABLE SC ( Sno CHAR(9), Cno CHAR(4), Grade INT CHECK(Grade>=0 AND Grade<=100), PRIMARY KEY (Sno, Cno), FOREIGN KEY (Sno) REFERENCES Student(Sno), FOREIGN KEY (Cno) REFERENCES Course(Cno) );6.2 典型业务实现
选课存储过程:
CREATE PROCEDURE SelectCourse( IN v_Sno CHAR(9), IN v_Cno CHAR(4), OUT v_Result INT ) BEGIN DECLARE cnt INT; -- 检查学生是否存在 SELECT COUNT(*) INTO cnt FROM Student WHERE Sno=v_Sno; IF cnt=0 THEN SET v_Result = -1; -- 学生不存在 RETURN; END IF; -- 检查课程是否存在 SELECT COUNT(*) INTO cnt FROM Course WHERE Cno=v_Cno; IF cnt=0 THEN SET v_Result = -2; -- 课程不存在 RETURN; END IF; -- 检查是否已选 SELECT COUNT(*) INTO cnt FROM SC WHERE Sno=v_Sno AND Cno=v_Cno; IF cnt>0 THEN SET v_Result = -3; -- 已选该课程 RETURN; END IF; -- 执行选课 INSERT INTO SC(Sno, Cno) VALUES(v_Sno, v_Cno); SET v_Result = 1; -- 选课成功 END;成绩统计视图:
CREATE VIEW StudentGPA AS SELECT S.Sno, S.Sname, AVG(SC.Grade) AS AvgGrade FROM Student S LEFT JOIN SC ON S.Sno=SC.Sno GROUP BY S.Sno, S.Sname;7. 数据库安全与优化
7.1 权限管理实例
-- 创建角色 CREATE ROLE StudentRole; CREATE ROLE TeacherRole; -- 为学生角色授权 GRANT SELECT ON StudentGPA TO StudentRole; -- 为教师角色授权 GRANT SELECT, UPDATE ON SC TO TeacherRole; -- 用户绑定角色 CREATE USER 'stu001' IDENTIFIED BY 'pass123'; GRANT StudentRole TO 'stu001';7.2 性能优化策略
查询优化技巧:
-- 避免全表扫描 EXPLAIN SELECT * FROM Student WHERE Sname LIKE '张%'; -- 合理使用索引 CREATE INDEX Idx_Dept ON Student(Dno); -- 分页查询优化 SELECT * FROM Student ORDER BY Sno LIMIT 20 OFFSET 40;数据库维护:
-- 定期分析表 ANALYZE TABLE Student; -- 备份数据 mysqldump -u root -p StudentDB > backup.sql在实际项目开发中,我曾遇到一个性能问题:当学生数据超过10万条时,分页查询变得异常缓慢。通过分析执行计划发现缺少合适索引,添加组合索引(Sdept,Sno)后,查询速度提升了20倍。这个案例让我深刻理解了索引对性能的关键影响。