简介:这份PPT课件面向高校计算机及相关专业学生,聚焦数据库系统概论第4章关系数据库标准语言SQL,帮助读者系统掌握SQL的核心概念与基础语法。内容从SQL概述切入,讲解其一体化、非过程化、面向集合等语言特点,并梳理数据定义、数据操纵、数据查询、数据控制及视图五大功能分类,重点展开基本表的创建、修改与删除,涵盖CREATE TABLE语法结构、数值型与字符型等数据类型,以及主键、外键、非空、唯一、检查等完整性约束条件,配合职工与部门关系模式建表实例加深理解。资源为单个PPT文件,压缩包约428KB,轻量便于课堂演示与课后复习。目前已有100人学习,适合作为数据库课程同步讲义或期末复习提纲,帮助读者快速建立SQL知识框架并对照实例巩固建表与约束的写法。
1. 从一份 PPT 说起:为什么 SQL 这块地基值得反复砸
很多人第一次接触《数据库系统概论》第 4 章这份 PPT,是在期末复习或者考研冲刺的节点上。它讲的是关系数据库标准语言 SQL,覆盖 SQL 概述、数据定义、数据查询、数据操纵、视图五大块。乍一看像课件,实际上它是一份把 SQL 九大动词、约束体系、建表语法串成一条线的浓缩讲义。你如果正在补数据库基础、准备面试里的 SQL 语句复习,或者带新人过一遍数据定义语句,这份资料能直接当骨架用。它不教你某个具体数据库的骚操作,而是把标准 SQL 的语法结构、约束分类、数据类型这些底层规则讲清楚。地基砸实了,后面写慢 SQL 优化、看执行计划、做数据迁移才不至于翻车。
2. SQL 概述与九大动词:先搞清这门语言到底管多宽
2.1 SQL 的定位与一体化特征
SQL 全称 Structured Query Language,结构化查询语言。名字里带“查询”,但它的能力远不止查询。这份 PPT 里反复强调一个词:一体化。它集数据定义、数据查询、数据更新和数据控制于一体,能覆盖数据库生命周期中的全部活动。什么意思?你建库建表、插数据、查数据、改数据、删数据、授权收权,全用同一套语言完成,不需要在几种工具之间来回切换。
PPT 里还提到一个关键点:SQL 面向集合。它的操作对象是集合,运算结果是集合,一次插入、删除、更新的对象也可以是集合。这一点和很多过程化语言的操作方式不同。你写一条 UPDATE,可能影响一万行,也可能影响零行,SQL 不关心逐行处理,它关心的是“满足条件的那个集合”。理解这一点,后面写 WHERE 条件、写 JOIN 的时候,脑子里装的应该是集合运算,而不是循环。
另一个特征是高度非过程化。你只需要指出“做什么”,不必指明“怎么做”。比如你要查所有年龄大于 16 的学生,你写 SELECT * FROM Student WHERE Age > 16,至于数据库是用索引扫还是全表扫,那是优化器的事。这个特征降低了使用门槛,但也埋了一个坑:写 SQL 的人容易忽略性能,因为“怎么做”被藏起来了。后面讲慢 SQL 优化的时候,这个坑会反复出现。
PPT 还提到 SQL 的两种使用方式:交互式独立使用,或者嵌入宿主语言(比如 VC、VB、Delphi、PB)中使用,语法结构一致。这意味着你在 Navicat 里敲的 SQL,和你在 Python 里通过驱动执行的 SQL,核心语法是同一套。区别只在于嵌入方式、参数绑定和结果集处理。
2.2 九大动词与功能分类
PPT 把 SQL 的核心功能压缩到九个动词,这个归纳很实用。我把它整理成一张表,方便对照记忆:
| 功能分类 | 命令动词 | 说明 |
|---|---|---|
| 数据定义 | CREATE、DROP、ALTER | 建表、删表、改表结构 |
| 数据操纵 | INSERT、UPDATE、DELETE | 增、改、删数据 |
| 数据查询 | SELECT | 查数据,SQL 里最复杂的一块 |
| 数据控制 | GRANT、REVOKE、COMMIT、ROLLBACK | 授权、收权、提交、回滚 |
这里注意一个细节:PPT 在数据控制里把 COMMIT 和 ROLLBACK 也列进去了,有些教材只列 GRANT 和 REVOKE。这个差异不影响理解,但说明这份资料在分类上偏向事务控制的完整性。你如果拿它当复习提纲,建议把 COMMIT 和 ROLLBACK 归到事务管理里单独记,避免和权限控制混淆。
九大动词里,SELECT 是唯一一个属于查询的,但它的复杂度远超其他八个。PPT 后面用了一整节讲数据查询,包括单表查询、连接查询、嵌套查询、集合查询。实际工作中,你写十行 SQL,八行是 SELECT,剩下两行是 INSERT 和 UPDATE。所以 SELECT 的功夫下多深都不为过。
2.3 SQL 的应用生态
PPT 列举了 SQL 的应用范围:Oracle、Sybase、Informix、Ingres、DB2、SQL Server、Rdb 等大型数据库管理系统实现了 SQL;Dbase、Foxpro、Access 等 PC 机数据库管理系统部分实现了 SQL;可以在 HTML 中嵌入 SQL 语句,通过 WWW 访问数据库;在 VC、VB、Delphi、PB 中也可嵌入 SQL 语句。
这段内容写于早期,但核心判断至今成立:SQL 是关系数据库的标准语言,是关系数据库的基础。Oracle、SQL Server、DB2 都使用 SQL。很多数据库产品还对 SQL 进行了再开发与扩展,比如 Oracle 提供的 PL/SQL 就是对 SQL 的一种扩展。你在实际工作中遇到的 MySQL、PostgreSQL、Spark SQL,本质上都是 SQL 的方言实现。标准 SQL 是底子,方言是上层建筑。底子不牢,换一个数据库就得重新学一遍。
提示:如果你正在准备面试里的 SQL 语句复习,建议先把九大动词和功能分类默写一遍,再往下看数据定义。这个框架能帮你把零散的语法点挂上去。
3. 数据定义:建表语句里的约束体系与数据类型选型
3.1 CREATE TABLE 的三段式结构
PPT 把创建基本表的语法拆成三个组成部分:列名、数据类型、完整性约束条件。语法骨架如下:
CREATE TABLE <基本表名> ( <列名> <数据类型> [列级完整性约束条件] [, <列名> <数据类型> [列级完整性约束条件]] ... [, 表级完整性约束条件] );这个结构看起来简单,但实际写的时候,新手最容易在三个地方出问题:一是约束条件放错位置,二是数据类型选错,三是命名不规范。PPT 专门列了建表注意事项,我结合自己的经验逐条说。
表名或列名不得超过 30 个字符。这个限制来自早期数据库的实现,现在很多数据库已经放宽了,但养成短命名的习惯没坏处。命名规则:第一个字符必须是字母,后面可以跟字母、数字、三个特殊符号(_、$、#),表名或列名中不可以包含空格。一个用户中表名要唯一,一个表中列名要唯一。表名和列名不区分大小写,但显示出来都是大写。保留字不能用作表名或列名。
这里有一个血泪经验:用保留字做列名,比如把列名叫order、group、desc,建表的时候可能不报错,但后面写查询的时候必须加引号或者转义,否则直接语法错误。我见过有人把订单表的列名叫order,结果所有查询都得写成SELECT \order` FROM ...`,维护起来极其难受。所以建表之前,先查一下数据库的保留字列表,花五分钟能省后面五小时的排查。
3.2 数据类型:数值、字符、位串、时间、布尔
PPT 把数据类型分成五类,我按实际使用频率重新排一下:
数值型里,INTEGER(可简写 INT)和 SMALLINT 用于整数,NUMERIC(p,s) 用于精确数值,FLOAT(p)、REAL、DOUBLE PRECISION 用于浮点数。实际建表的时候,金额字段我一般用 NUMERIC 或 DECIMAL,不用 FLOAT,因为浮点数有精度问题。你如果做过财务相关的表,应该知道 0.1 + 0.2 不等于 0.3 的经典问题。字符型里,CHAR(n) 是固定长度,VARCHAR(n) 是可变长度。PPT 特别标注:VARCHAR 的 n 不可省略。这个细节很多人忽略,写 VARCHAR 不带长度,有些数据库直接报错,有些给个默认值,行为不一致。位串型 BIT(n) 和 BIT VARYING(n) 在实际业务里用得少,但做权限位运算或者状态标记的时候有用。时间型 DATE 包含年月日,格式 YYYY-MM-DD;TIME 包含时分秒,格式 HH:MM:SS。布尔型 BOOLEAN 的值是 TRUE 或 FALSE。
选数据类型的时候,我一般遵循几个原则:能用小类型就不用大类型,比如年龄用 SMALLINT 不用 INT;金额用 NUMERIC 不用 FLOAT;字符串长度留余量但别太夸张,VARCHAR(10) 能存下的名字,别开 VARCHAR(255)。这些选择在单表数据量小的时候看不出差别,但数据量上千万之后,类型选错会导致存储膨胀和索引效率下降。
3.3 约束条件:主键、外键、非空、唯一、检查
PPT 把约束条件分成五类:主键约束(PRIMARY KEY)、外键约束(FOREIGN KEY)、非空约束(NOT NULL)、唯一约束(UNIQUE)、检查约束(CHECK)。并且明确指出:基本表的完整性约束可定义为两级——表级约束和列级约束。上述五种约束条件均可作为列级完整性约束条件,但非空约束不可以作为表级完整性约束条件,而其他四种也可以作为表级完整性约束条件。
这个“非空约束不能做表级约束”的细节,很多人记不住。我自己的记法是:非空约束只针对单个列,天然就是列级的;而主键、外键、唯一、检查可能涉及多个列的组合,所以需要表级定义。比如联合主键 PRIMARY KEY(eno, dno),必须写在表级。
PPT 给了两个对比示例,一个是列级约束,一个是表级约束。我把它们放在一起,方便对照:
-- 列级约束写法 CREATE TABLE emp ( eno number(6) primary key, ename varchar2(10) unique, sex varchar2(3) not null, dno varchar2(10) references dept(dno), sal number(6) check(sal > 1000 and sal <= 10000) ); -- 表级约束写法 CREATE TABLE emp ( eno number(6), ename varchar2(10), sex varchar2(3) not null, dno varchar2(10), sal number(6), primary key(eno), unique(ename), foreign key(dno) references dept(dno), check(sal between 1000 and 10000) );逻辑说明:列级约束直接跟在列定义后面,适合单列约束;表级约束写在所有列定义之后,适合多列组合约束。参数说明:number(6)表示最多 6 位数字,varchar2(10)是 Oracle 的可变字符串类型,references dept(dno)表示外键引用 dept 表的 dno 列。注意check(sal between 1000 and 10000)和check(sal > 1000 and sal <= 10000)在边界上等价,但 BETWEEN 写法更简洁。
PPT 还给了学生表的例子,所有约束均为列级:
CREATE TABLE Student ( Sno CHAR(8) PRIMARY KEY, /* 主键约束 */ Sname CHAR(10) UNIQUE, /* 唯一约束 */ Sex CHAR(3) NOT NULL, /* 非空约束 */ Age INT CHECK(Age > 16), /* 检查约束 */ Dept VARCHAR(15) );这个例子适合拿来练手。你可以把它复制到 MySQL 或 PostgreSQL 里跑一遍,然后把约束逐个删掉,观察插入非法数据时的报错信息。报错信息是理解约束的最好教材。
注意:外键约束的列和被引用列的数据类型必须兼容,长度可以不同但类型要匹配。我见过有人用 INT 做外键引用 VARCHAR 的主键,建表时报错,排查了半天才发现是类型不匹配。
4. 数据查询与数据操纵:SELECT 的集合思维与增删改的边界
4.1 SELECT 的集合操作方式
PPT 在 SQL 特点里强调“面向集合的操作方式”,这个特征在 SELECT 里体现得最明显。你写一条 SELECT,返回的是一个结果集,这个结果集可以来自单表,也可以来自多表连接,还可以来自嵌套查询。PPT 把数据查询单独列为一节,说明它的分量。
实际写查询的时候,我一般按这个顺序思考:先确定数据来自哪几张表,再确定连接条件,然后确定过滤条件,最后确定返回哪些列。这个顺序和 SQL 的执行顺序不完全一致,但符合人的思维习惯。SQL 的执行顺序大致是 FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY,你如果按执行顺序写,反而容易乱。
连接查询是 SELECT 里的重头戏。PPT 提到了连接运算,实际工作中最常用的是 INNER JOIN、LEFT JOIN、RIGHT JOIN。我自己的习惯是:能用 INNER JOIN 就不用 LEFT JOIN,因为 LEFT JOIN 的驱动表选择会影响性能,而且容易产生 NULL 值,后续处理麻烦。如果业务确实需要保留左表全部记录,再用 LEFT JOIN,并且明确知道右表可能为 NULL 的列。
嵌套查询是另一个容易翻车的地方。PPT 里提到合并、求差、相交、乘积、投影、选择、连接等关系运算,这些在 SQL 里都有对应的写法。嵌套查询写多了,可读性会下降,我一般建议把嵌套查询改写成 JOIN,除非嵌套查询能用 EXISTS 或 IN 走半连接优化。慢 SQL 优化的时候,嵌套查询往往是重点排查对象。
4.2 INSERT、UPDATE、DELETE 的集合影响
数据操纵三个动词:INSERT、UPDATE、DELETE。PPT 把它们归在数据操纵里,和查询分开。实际使用的时候,这三个动词的风险比 SELECT 高得多,因为 SELECT 写错了最多查不出数据,UPDATE 和 DELETE 写错了可能直接丢数据。
INSERT 的集合特征体现在批量插入。你可以写一条 INSERT 插入一行,也可以写 INSERT INTO ... SELECT ... 插入一批。批量插入的时候,注意事务大小,一次插入几十万行可能导致日志膨胀和锁等待。我一般会分批提交,比如每 1000 行提交一次。
UPDATE 和 DELETE 的集合特征更明显。你写 UPDATE emp SET sal = sal * 1.1 WHERE dno = 'D001',影响的是整个部门的人。写之前,我强制自己先用 SELECT 把 WHERE 条件跑一遍,确认影响行数符合预期,再把 SELECT 改成 UPDATE 或 DELETE。这个习惯救过我很多次。PPT 里没有展开讲这个,但这是实操中必须养成的肌肉记忆。
提示:执行 UPDATE 或 DELETE 之前,先开事务,执行完确认影响行数,再 COMMIT。如果发现不对,ROLLBACK 还来得及。这就是 PPT 里把 COMMIT 和 ROLLBACK 归入数据控制的用意。
4.3 视图:PPT 里一笔带过但实际很重的一块
PPT 的目录里列了第五节视图,但正文没有展开。视图在实际工作中的价值,我补充几点。视图是一个虚拟表,不存储数据,只存储查询定义。它的好处是简化复杂查询、控制权限、屏蔽底层表结构变化。比如你有一张宽表,不同角色只能看部分列,你可以给每个角色建一个视图,只暴露该看的列。
视图的坑在于性能。视图展开后可能变成很复杂的查询,如果视图里嵌套了视图,执行计划可能失控。我一般建议视图嵌套不超过两层,并且对视图的查询也要做慢 SQL 监控。另外,视图的更新限制比较多,不是所有视图都能 UPDATE,具体取决于数据库实现和视图定义。
5. 避坑与排查:建表和查询里最容易翻车的五件事
5.1 现象:建表时报“无效的数据类型”
原因:用了数据库不支持的别名,或者 VARCHAR 没写长度。比如在 Oracle 里写 VARCHAR 不带长度,或者用 BOOLEAN 类型但数据库不支持。
解决:先确认数据库版本和类型支持列表。Oracle 里用 VARCHAR2(n),MySQL 里用 VARCHAR(n),布尔类型用 TINYINT(1) 或 ENUM 替代。建表之前,把数据类型对照表过一遍。
5.2 现象:插入数据时报“违反检查约束”
原因:CHECK 约束的条件和插入值不匹配,或者 CHECK 约束里用了不支持的非确定性函数。
解决:先用 SELECT 把 CHECK 条件里的表达式跑一遍,确认边界值。注意 BETWEEN 的边界是闭区间,BETWEEN 1000 AND 10000包含 1000 和 10000。如果业务要求开区间,得写成> 1000 AND < 10000。
5.3 现象:外键约束导致插入顺序受限
原因:子表插入时,父表还没有对应的主键值。或者删除父表记录时,子表还有引用。
解决:调整插入顺序,先插父表再插子表。删除时先删子表再删父表,或者用 ON DELETE CASCADE 级联删除。但级联删除要慎用,我一般不建议在核心业务表上用,因为删一条父表记录可能带走一批子表数据,风险太高。
5.4 现象:UPDATE 或 DELETE 影响行数远超预期
原因:WHERE 条件写漏了,或者条件字段有 NULL 值导致匹配异常。
解决:执行前先用 SELECT COUNT(*) 确认影响行数。WHERE 条件里涉及 NULL 的时候,用 IS NULL 或 IS NOT NULL,不能用 = NULL。这个坑在 SQL 语句复习里经常考,实际工作中也经常踩。
5.5 现象:查询结果里出现重复行
原因:连接查询时,一对多关系导致左表记录重复。或者 SELECT 的列里包含了导致重复的字段。
解决:先确认业务逻辑是否需要去重。如果需要,用 DISTINCT 或者 GROUP BY。但 DISTINCT 有性能代价,数据量大时慎用。更好的做法是检查连接条件,看能不能通过调整 JOIN 方式避免重复。SQL 语句去重是热搜里的高频问题,核心还是搞清楚数据关系,而不是无脑加 DISTINCT。
6. 进阶技巧:把这份 PPT 变成可执行的 SQL 练习清单
这份 PPT 的价值不在于读一遍,而在于把它变成可执行的练习。我一般会按下面的步骤把一份课件拆成练习清单。
第一步,把 PPT 里的建表示例全部敲一遍。不要复制粘贴,手敲。手敲的过程中,你会自然注意到标点符号、大小写、约束位置这些细节。PPT 里的 emp、dept、Student 三个表,足够覆盖主键、外键、非空、唯一、检查五类约束。
第二步,给每个表插入测试数据,然后故意插入非法数据,观察报错信息。比如给 Student 表的 Age 插入 15,看 CHECK 约束怎么报错;给 Sno 插入重复值,看主键约束怎么报错。报错信息是理解约束的最好教材,比看语法文档管用。
第三步,把列级约束改写成表级约束,再改回来。这个练习能帮你彻底搞清两级约束的边界,尤其是非空约束为什么不能做表级约束。
第四步,用 SELECT 把插入的数据查出来,然后逐步加 WHERE、JOIN、GROUP BY、HAVING、ORDER BY,观察结果集的变化。这一步的目的是建立集合思维,而不是逐行思维。
第五步,把 UPDATE 和 DELETE 的 WHERE 条件先写成 SELECT,确认影响行数,再改成 UPDATE 和 DELETE。这个习惯我坚持了很多年,从那以后我每次执行更新和删除之前,都强制走一遍 SELECT 确认影响范围。希望帮到你。
本文还有配套的精品资源,点击获取