ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

数据库核心概念:DBMS、三级模式、关系模型与索引

数据库核心概念:DBMS、三级模式、关系模型与索引

简介:中南大学数据库课程试题文档面向高校数据库原理课程学习者与备考学生,围绕数据库管理系统基础、三级模式结构、SQL语言、关系模型与关系代数、数据库保护及规范化设计等核心考点组织内容,兼顾课堂复习与考前自测。文档以复习总纲加试卷形式呈现,包含选择题、填空题、术语解释与简答题等题型,并配有参考答案,便于对照检查知识掌握情况;题目覆盖DBMS与文件系统的区别、ER模型键约束、视图与基表关系、聚簇与非聚簇索引、事务ACID、并发控制、四种异常以及1NF至3NF的转化条件等细节。压缩包内共1个doc文件,大小约164KB,篇幅紧凑,适合打印或离线查阅。已有358人学习,可作为课程期末复习、考研专业课梳理和数据库基础知识自测的参考资料,帮助读者快速定位重点并借助答案理解常见易错点。

1. 数据库是什么:一个不会记串行的班级账本

选课系统开放的那一分钟,几千个人同时点同一门课,页面上的余量从 30 变成 0,中间没有出现两个人抢到同一个名额——这背后站着的就是数据库。通俗地说,数据库是长期存储在计算机内、有组织、可共享的数据集合。它不只是“一堆表”,更像一本有规矩的公共账本:数据按结构存放,谁能读、谁能改、改错了怎么恢复,都有专门机制管着。搞懂它,你就能明白为什么同样存数据,有人用一张表搞定,有人却要拆成三张表;也能看懂“事务”“索引”“范式”这些词到底在防什么。它不神秘,本质是把现实世界里的关系和规则,翻译成计算机能稳定执行的形式。

2. 为什么要有数据库管理系统:文件管理留下的三个坑

2.1 人工管理与文件管理:数据管理的前两个阶段

在没有数据库的年月,数据管理大致走过两条路。最早是人工管理阶段,数据不长期保存,程序自己管数据,换个程序就得重新录一遍,数据之间也谈不上共享。后来进入文件管理阶段,操作系统用文件来存数据,数据可以长期保留,文件内部也有了结构,比如一个 CSV 文件里固定有“学号、姓名、成绩”几列,这已经比人工管理前进了一大步。

但文件管理有个天生的短板:文件内部有结构,文件与文件之间没有结构。一个班级的名单放在一个文件里,成绩放在另一个文件里,选课记录再放一个文件里,三份文件各记各的。同一个学生的姓名在三个地方各存一遍,改了一处忘了另外两处,数据就对不上了。程序还得自己记住文件的格式,哪天文件加了一列,程序可能直接跑不起来。

打个比方,文件管理就像三个人各拿一本账本记同一笔生意:每个人记得都很认真,但三本账之间没有对账机制,月底一碰,数字对不上,谁也不知道哪本是对的。数据冗余、数据不一致、程序与数据绑得太死,这三个坑,就是数据库管理系统要填的。

2.2 DBMS 多做了什么:从“各自记账”到“统一账房”

数据库管理系统(DBMS)的位置,夹在用户和操作系统之间,是一层专门管数据的软件。它的第一件事是数据定义:用 DDL 把“学生有哪些列、每列什么类型、主键是谁”写进数据字典,而不是散落在各个程序里。第二件事是数据操纵:用 DML 完成插入、删除、更新、查询,让程序不用关心数据具体存在哪个文件的第几个字节。

第三件事是数据控制,也是它和文件系统拉开差距的地方。多个用户同时选课,DBMS 要做并发控制,避免两个人改同一行互相覆盖;插入一条成绩,DBMS 要检查学号在 student 表里是否存在,这是完整性检查;某个用户只能看自己院系的数据,DBMS 要做权限控制;系统突然断电,DBMS 要能根据日志把数据恢复到一致状态。第四件事是数据库维护,包括转储、恢复、重组和性能监控,这些工作通常由数据库管理员(DBA)来统筹。

数据库系统的特点,常被概括成四条:数据结构化,数据面向全局组织,而不是面向某个程序;共享性高、冗余度低、容易扩展;数据独立性高,程序不因为存储方式改变而重写;数据由 DBMS 统一管理和控制。把这四条和文件管理对照着看,就能明白为什么复习资料里反复强调“DBMS 的引入是为了克服文件系统的局限性”。

2.3 DB、DBMS、DBS、DBAS:四个缩写别再混着叫

这四个词长得像,考试里却经常单独拎出来问。用图书馆打个比方就好记了:书是 DB,图书馆的管理系统和管理员是 DBMS,整个图书馆连同藏书、设备、管理员、读者是 DBS,而面向读者的借阅服务台是 DBAS。

缩写全称指什么图书馆类比
DBDatabase长期存储、有组织、可共享的数据集合书架上的书
DBMS数据库管理系统位于用户与操作系统之间的数据管理软件管理员和管理系统
DBS数据库系统数据库、DBMS、应用程序、DBA、用户和硬件的整体整个图书馆
DBAS数据库应用系统面向具体业务的应用软件借阅服务台

容易出错的地方在于把 DBMS 和 DBS 当成一回事。DBMS 只是软件,DBS 是包含人、硬件、软件、数据的完整系统。另一个常见混淆是 DBAS 和 DBS:DBAS 是跑在 DBMS 之上、给最终用户用的那层应用,比如选课界面;DBS 的范围更大,连数据库本身和管它的人都算进去。把这层关系理清,后面看到“数据库系统由哪些部分组成”这类题,就不会只答一个 DBMS 了。

3. 三级模式与两级映像:数据库的“三层楼”和两部电梯

3.1 模式、外模式、内模式:三层楼各住着谁

数据库的三级模式,是理解数据独立性的入口。模式也叫概念模式或逻辑模式,描述的是全体数据的逻辑结构和特征,一个数据库只有一个模式,它像整栋楼的户型总图。外模式也叫子模式或用户模式,是某个用户或某类应用能看到的那部分数据的逻辑结构,可以有多个,像每户人家窗户里看到的那一片。内模式也叫存储模式,描述数据在磁盘上怎么存、用什么存取方法、要不要压缩加密,一个数据库只有一个,像楼的地基、管线和仓库位置。

层次别名描述什么数量对应 SQL 层面
外模式子模式、用户模式用户看到的局部逻辑结构多个视图、权限可见的列
模式概念模式、逻辑模式全体数据的全局逻辑结构一个基表的整体设计
内模式存储模式物理存储结构与存取方法一个文件组织、索引、存储参数

用一句话概括:模式管“有哪些数据、之间什么关系”,外模式管“你能看到哪一部分”,内模式管“数据到底放在哪儿”。三级模式结构配上两级映像,才是数据库系统体系结构的完整答案,单选题里常见的“三级模式结构和两级映象”说的就是它。

3.2 两级映像:物理独立性和逻辑独立性从哪来

两级映像像两部电梯,把三层楼连起来。第一部是外模式/模式映像,它把某个用户的视图和全局逻辑结构对应起来。当全局逻辑结构发生变化,比如给表增加了一列,只要调整这层映像,用户原来的外模式可以保持不变,应用程序也不用改,这叫逻辑独立性。第二部是模式/内模式映像,它把全局逻辑结构对应到物理存储。当存储方式发生变化,比如换了存储设备、调整了索引组织,只要改这层映像,模式可以不动,应用程序更不用动,这叫物理独立性。

复习资料里有一道很典型的题:要保证数据库物理数据独立性,需要修改的是模式与内模式的映射。反过来,要保证逻辑数据独立性,改的是模式与外模式的映射。把这两句话记住,比背整段定义管用。

举个具体的例子。某高校的选课系统最早把数据放在一种普通的文件组织里,后来数据量涨了,换成另一种更适合范围查询的存储组织。应用层的查询语句没有改一行,因为改的是内模式和模式/内模式映像。再比如,学校要给某张表加一个“备注”列,全局模式变了,但某个只关心“学号、姓名”的查询视图不受影响,因为外模式/模式映像把这层变化挡在了外面。

3.3 视图与基表:为什么视图不能随便当表改

视图是从一个或多个基表,甚至从其他视图导出来的虚表。数据库里只存视图的定义,不存视图对应的数据,数据仍然在基表里。视图的好处很实在:可以把复杂的多表连接包装成一个简单的名字,查询时不用每次都写一长串条件;可以只暴露部分列,起到一定的安全隔离作用;也可以在全局逻辑结构变化时,给应用保留一个稳定的接口。

但视图不是万能的,尤其是在更新这件事上。视图的更新最终要映射回基表,如果视图来自多表连接、分组聚合、去重或者包含计算列,数据库往往不知道该改哪一行,于是干脆不允许更新。这就是单选题里“在视图上不能完成的操作”的考点:在视图上可以查询,可以再定义视图,但“在视图上定义新的基本表”是不成立的,基本表得用 CREATE TABLE 建。

创建视图时还可以加 WITH CHECK OPTION,作用是让通过视图插入或更新的行必须满足视图定义里的条件,否则拒绝操作。比如视图只包含“某个系”的学生,加上这个选项后,往视图里插一个其他系的学生就会被挡下来。子模式 DDL 描述的正是这种局部逻辑结构,而不是全局逻辑结构或物理存储结构,这一点在选择题里也经常出现。

4. 数据模型怎么落地:ER图、键约束和关系代数

4.1 数据模型三要素:结构、操作、约束

数据模型不是一张图,而是一套描述数据的规矩,通常包含三部分:数据结构,说明数据本身怎么组织、之间有什么联系;数据操作,说明能对这些数据做哪些操作,比如增、删、改、查;完整性约束,说明数据必须满足哪些规则,比如学号不能重复、成绩不能超过满分。评价一个数据模型好不好,也主要看这三件事:能不能真实地模拟现实世界,容不容易被人理解,好不好在计算机上实现。

数据模型分几个层次。概念模型离人近、离机器远,最常用的是 ER 模型;逻辑模型离机器近一些,包括层次模型、网状模型和关系模型;物理模型则直接对应存储细节。关系模型用二维表来表示数据,有关系代数作为数学基础,数据独立性也高,所以成了当前应用最广泛的数据模型。选择题里问“当前应用最广泛的数据模型”,答案就是关系模型;问“反映现实世界中实体及实体间联系的信息模型”,答案是 ER 模型。

4.2 ER模型:实体、属性、联系怎么画

ER 模型用三样东西描述现实:实体是客观存在的事物,比如学生、课程;属性是实体的特征,比如学号、姓名、课程名;联系是实体之间的关联,比如学生选修课程。画成图,实体用矩形,属性用椭圆,联系用菱形。联系有三种类型:一对一,比如一个人对应一个身份证号;一对多,比如一个系有若干学生,一个学生只属于一个系;多对多,比如一个学生可以选多门课,一门课也可以被多个学生选。

把 ER 图转成关系模型,是数据库逻辑设计阶段的核心任务。实体通常转成一张表,实体的键成为表的键。一对多联系可以在“多”的那一端加一个外键,指向“一”的那一端。多对多联系则必须单独建一张表,这张表的码由两端实体的码组合而成,比如选课表(学号,课程号,成绩),学号和课程号合起来才能唯一确定一条选课记录。

这里有个容易翻车的点:多对多联系不能靠在某张表里加一列来解决。加一列只能存一个值,存不下“多个”,所以必须拆表。复习资料里那道“同一本书允许一个读者多次借阅,但不能同时对一种书借多本”的题,考的就是码的组合:借阅关系的码不是单独的书号,也不是单独的读者号,而是书号加读者号再加借期,因为同一个读者可以多次借同一本书,只有加上借期才能唯一区分。

4.3 键约束与完整性:主键、外键、唯一性各管什么

关系模型里的“键”,是一组能唯一标识一条记录的属性。超键是能唯一标识元组的属性组,但可能包含多余的列;候选键是最小的超键,去掉任何一个属性都不能唯一标识;主键是从候选键里挑出来实际使用的那个;外键是引用另一个关系主键的属性组。用一句话区分:候选键是“有资格当主键的”,主键是“已经上岗的”,外键是“指向别人家主键的”。

完整性约束主要有三类。实体完整性要求主键不能为空、不能重复,否则一条记录就没法被唯一认出来。参照完整性要求外键要么为空,要么等于被参照关系中某个真实存在的主键值,不能指向一个不存在的东西。用户定义完整性则是具体业务加的规则,比如年龄必须在 18 到 60 之间、成绩必须在 0 到 100 之间。

表内还有更细的约束:域约束规定某一列的取值范围和数据类型;唯一性约束规定某一列的值不能重复,但通常允许为空;主键约束则是非空加唯一。外键在删除和更新时还有几种策略:级联删除,被参照的记录删了,引用它的记录也跟着删;受限删除,只要有记录还在引用,就拒绝删除;置空值删除,把引用方的外键置为空。插入时也有受限插入和递归插入两种策略。这些策略不是死记硬背的条目,而是设计表时真要做出的选择:删一个系之前,是把这个系的学生一起删掉,还是先把他们转到别的系,还是干脆不允许删,取决于业务能不能承受。

4.4 关系代数:五种基本运算和那个最难的除法

关系代数是用运算来表达查询的语言。传统集合运算有并、交、差、笛卡尔积,专门的关系运算有选择、投影、连接、除法。考试里常问“五种基本关系代数运算”,标准答案是并、差、笛卡尔积、选择、投影,也就是 ∪、−、×、π、σ;交、连接、除法都可以由这五种导出。

选择是从行的角度挑记录,记作 σ,比如 σ 年龄≥18 ∧ 年龄≤22(学生),意思是把学生表里年龄在 18 到 22 之间的行选出来。投影是从列的角度挑属性,记作 π,比如 π 姓名,所在系(学生),意思是只保留姓名和所在系两列,并且自动去掉重复行。连接是把两张表按条件拼起来,等值连接和自然连接的区别在于,自然连接会去掉重复的属性列,等值连接不会。

除法是这几类运算里最容易让人懵的。它的直观含义是“对所有”:π 学号,课程号(选课)÷ π 课程号(课程),得到的是选修了全部课程的学生学号。因为除法的结果要满足“对右边关系里的每一个值,左边关系里都有对应的组合”。复习资料里那道“查询选修了全部课程的学生学号和姓名”,就是除法的典型应用;如果不用除法,就得用 NOT EXISTS 嵌套两层来表达“不存在一门课他没选”。

再补一个常考的差集用法:求没有选修 5 号课程的学生学号,可以先投影出所有学号,再减去选修了 5 号课程的学生学号,写成 π 学号(学生)− π 学号(σ 课程号='5'(选课))。这类题的关键不是背符号,而是先想清楚“全集是什么、要排除什么”,再套运算。

4.5 SQL与索引:DDL/DML分工,聚簇与非聚簇

SQL 是关系数据库的标准语言,特点是综合统一、高度非过程化、面向集合、同一种语法既能交互使用也能嵌入到宿主语言里,而且语言简洁。它按功能分成几块:DDL 负责定义和修改数据库对象,典型语句是 CREATE、DROP、ALTER;DML 负责操作数据,典型语句是 INSERT、DELETE、UPDATE、SELECT;DCL 负责权限控制,典型语句是 GRANT 和 REVOKE。考试里问“属于 DDL 的语言”,答案就在 CREATE、DROP、ALTER 里选;问“属于数据更新的操作”,插入、删除、修改算,查询不算。

-- 建一张学生表:Sno 为主键,隐含非空且唯一 CREATE TABLE Student ( Sno CHAR(8) PRIMARY KEY, Sname VARCHAR(20), Ssex CHAR(1), Sage INT, Sdept VARCHAR(20) ); -- 在姓名列上建普通索引,加速按姓名查找 CREATE INDEX idx_student_name ON Student(Sname); -- 建一个只包含部分列的视图 CREATE VIEW v_student_basic AS SELECT Sno, Sname, Sdept FROM Student;

上面这段代码里,PRIMARY KEY 同时承担了非空、唯一和索引三重角色;CREATE INDEX 建的是普通索引;CREATE VIEW 只保存查询定义,不复制数据。不同数据库管理系统在聚簇索引的写法上略有差异,有的用 CLUSTERED 关键字,有的把主键默认组织成聚簇结构,具体要看产品文档,不能一概而论。

索引分聚簇和非聚簇,区别在于索引项的顺序和表中记录的物理顺序是否一致。聚簇索引的索引项顺序与记录的物理顺序一致,一个表通常只能有一个,因为一张表的物理顺序只能有一种;非聚簇索引的索引顺序与物理顺序无关,叶子节点存的是指向记录的指针或行号。聚簇索引适合范围查询,因为相邻的记录在物理上也挨着;非聚簇索引适合精确查找,查完索引还要再回表取数据。索引和 UNIQUE、PRIMARY 的关系也常被问到:主键和唯一约束通常会自动创建唯一索引来保证不重复,但索引本身是加速查询的物理结构,三者不是同一个概念。

5. 常见误区:这几组概念一混,后面全歪

5.1 主键、候选键、唯一索引:都是“不能重复”吗

易混点在于,这三者都和“唯一”沾边,初学者很容易把它们当成同一件事。为什么会混?因为建表时给某一列加上 PRIMARY KEY 或 UNIQUE,数据库确实都会阻止重复值,表面效果很像。

区分它们要看三个维度:是不是非空、能有几个、在哪一层。主键是选定的候选键,非空且唯一,一个表只能有一个;候选键是能唯一标识元组的最小属性组,可以有多个,主键只是其中一个;唯一索引是物理层面的索引结构,用来加速查询并顺便保证列值唯一,通常允许空值,一个表可以有多个。主键上一般会自动建唯一索引,但反过来说“唯一索引就是主键”就错了。考试里问“关系模式的码”,问的是候选键或主键,不是索引。

5.2 聚簇索引与非聚簇索引:顺序一致到底指什么

易混点在于,两个名字只差一个字,定义里又都出现“索引”和“顺序”。为什么会混?因为教材上的定义比较抽象,而实际建表时很多数据库会自动做主键索引,让人误以为主键就是聚簇索引。

区分的关键是“索引项的顺序和表中记录的物理顺序是否一致”。聚簇索引一致,所以它决定了数据在磁盘上的排列顺序,一个表只能有一个;非聚簇索引不一致,索引是独立的一套结构,叶子节点存的是指向真实记录的指针,一个表可以有多个。主键是不是聚簇索引,取决于数据库管理系统和建表时的设置,不是必然关系。复习资料里“索引项的顺序与表中记录的物理顺序一致的索引称为聚簇索引”,这句话本身就是最直接的区分标准。

5.3 丢失更新、读脏数据、不可重复读:并发三兄弟

易混点在于,这三种问题表现出来都是“读到的数据不对”。为什么会混?因为它们都发生在多个事务同时访问同一批数据的时候,名字又都带点“数据不一致”的味道。

区分要看“谁对谁做了什么”。丢失更新是两个事务读同一行、各自修改、后提交的覆盖了先提交的,先提交的那次修改丢了。读脏数据是一个事务读到了另一个事务还没提交的数据,对方后来回滚了,读到的就是脏的。不可重复读是同一个事务内两次读同一行,中间别人改了并提交,两次结果不一样。再往外还有一个幻读,指的是同一事务两次按条件查,第二次多出或少了几行,材料里没展开,但概念上要和不可重复读分开。

这三种问题的根源是并发操作没有隔离好,解决办法是靠并发控制,比如基于锁的协议。锁有粒度之分,锁数据库、锁表、锁页、锁行,粒度越小并发度越高、开销也越大。死锁是两个事务互相等对方释放锁,预防办法有一次封锁法和顺序封锁法,前者一次锁住所有要用的数据,后者按预先规定的顺序加锁。可串行化是判断并发调度是否正确的标准:一个并发调度的结果如果和某个串行调度的结果一样,它就是可串行化的。

5.4 部分依赖与传递依赖:1NF、2NF、3NF 的升级条件

易混点在于,部分依赖和传递依赖都发生在非主属性和候选键之间,都会带来冗余和异常。为什么会混?因为定义里都出现“非主属性”,不举个例子很难看出差别。

部分依赖是候选键的一部分就能决定某个非主属性。比如选课关系(学号,课程号,成绩,系名,系主任),候选键是学号和课程号的组合,但系名只由学号决定,不需要课程号,这就是部分依赖。传递依赖是非主属性决定了另一个非主属性,比如学号决定系名,系名又决定系主任,系主任就传递依赖于学号。

范式就是按这两个依赖一步步升级的。1NF 要求每列不可再分,不能出现“电话”一列里塞两个号码;2NF 在 1NF 基础上消除非主属性对候选键的部分依赖;3NF 在 2NF 基础上消除非主属性对候选键的传递依赖;BCNF 更进一步,连主属性对候选键的部分和传递依赖也要消除。关系模式设计不好会带来四类问题:数据冗余、插入异常、删除异常、更新异常。分解关系模式时要满足两个准则:无损连接和保持函数依赖,缺一个都可能在分解后丢信息或丢约束。

6. 什么时候该用数据库思维,什么时候别硬套

数据库不是越用越显得专业,它是有适用边界的。判断要不要上数据库,我习惯先问三个问题:这份数据会不会被多个人同时改?改错了能不能忍?查询会不会越来越复杂?三个里有两个答“是”,数据库基本值得上;三个都答“否”,先老老实实用文件可能更省事。

场景更适合的方案原因
多人同时选课、抢名额关系数据库需要事务、并发控制和完整性约束
只有几十行配置的单机小工具配置文件上数据库反而增加部署和运维成本
写多读少的日志、埋点先写文件再批量入库实时一致性要求低,直接入库压力大
需要长期维护、复杂查询的业务数据关系数据库表结构稳定,查询和权限管理成熟
一次性数据清洗脚本内存或临时文件用完就丢,不需要持久化和并发控制

先说什么时候该用。数据量大、多人共享、需要长期维护、需要保证一致性的时候,数据库的价值就出来了。比如一个模拟项目 X,最初用几个文本文件存学生、课程、选课记录,单机跑没问题;后来加了教师端和管理端,三个人同时改同一份选课记录,文件方案立刻翻车,后保存的覆盖了前面的。换成数据库后,事务和锁把这类问题挡在了外面,虽然多了一层服务要维护,但换来的是数据不再对不上。

再说什么时候别硬套。一个只有几十行配置的小工具,把配置塞进数据库,部署时还得额外带一个数据库服务,安装包从几兆变成几百兆,用户装完还得先启动服务,这就是典型的过度设计。日志、埋点这类写多读少、可以容忍最终一致的数据,也不一定非要实时写进关系表,先落文件再批量入库,反而更稳。单机小工具如果确实需要结构化查询,用嵌入式数据库就够了,不必上完整的客户端/服务器架构。

我踩过一次坑:给一个离线小工具加了数据库,结果用户环境里没有服务,装了三遍都没跑起来,最后改回配置文件,十分钟搞定。从那以后我每次开新项目,都强制先把那三个问题过一遍,再决定要不要建表。希望帮到你——如果你正在准备数据库相关的考试或项目,这份按章节整理、带题目和答案的资料,可以拿去对着过一遍,比自己从零梳理省不少时间。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进