【数据库】第三章 关系数据库标准语言SQL

3.1 SQL概述

结构性查询语言,是关系数据库的标准语言

SQL是一个通用的的关系数据库语言

3.1.1 SQL的产生和发展

3.1.2 SQL的特点

1.综合统一

2. 高度非过程化

3. 面向集合的操作方式

4. 以同一种语法结构提供多种使用方式

5. 语言简洁,易学易用

3.1.3 SQL的基本概念

基本表

就是关系模型中的关系

其实就是三级模式

索引类比是书的目录 能够快速查找到需要的表

存储文件

视图

与外面应用程序对接的接口 (对应外模式)


3.2 学生-课程数据库

学生-课程关系模式S-T包含三个表

学生表

课程表(这个表存在内部外码)

Cpno先行课的也是用的课程号 引用自己同一课程表中已存在的课程号(Cno),这就形成了 "关系内部的外码"。

学生选课表

外码(不是自己的码 是别人的码)


3.3 数据定义

3.3.1 模式的定义与删除

1.定义模式

定义模式就是定义一个框架

说明:

1.没有定义模式名时候 用户名就是模式名

2.定义模式可以接受定义表 视图 索引的子句

3.执行创建模式语句必须拥有DBA(数据库管理员)权限,或者有创建模式的权限

2. 删除模式

说明:


3.3.2 基本表的定义、删除与修改

1.定义基本表

基本表是关系模式里面的 一个模式可以定义多个表

说明:

方括号里面的可有可无(根据需要)尖括号整体代表一个东西 我们定义的时候不用再写尖括号

完整性约束(前面的三种:主题完整性 参照完整性 用户定义的完整性)这里一般用两种:

主体完整性:就是主码

参照完整性:前面的外码

**必须定义在表级的情况:**上面那个学生选课表SC 主码(Sno,Cno)参照了另外两个表 就必须定义在表级了

只要有主码外码都定义出来****只有主码参照了好几列才定义到表级(就是定义完列过后再定义主码)

【例】定义一个学生表

CHAR代表字符型 (9)是字符长度 后面CHAR(2)是因为汉字是两个字符

SMALLINT是短整型的意思

【例】定义课程表

外码 简单记就是某个属性(某一列/目)参照别人的主码 且不是自己主码 当这个别人是本身时 就是自引用类型的外码

这时候建议定义出来吧

【例】定义学生选课表

2.数据类型


3.3.3 索引的建立和删除

目的:大幅提升数据库的查询效率,就像给一本书建立目录一样,让数据库不用逐行扫描整张表,就能快速定位到需要的数据。查表里的内容

自动建立索引的:(就是方便查找的,不重复的效率肯定更高)

主键PRIMARY KEY;

唯一UNIQUE

1. 建立索引

CREATE [UNIQUE] [CLUSTER] INDEX<索引名> ON <表名>

说明:

【例】为学生课程数据库三个表建立索引

ASC (ascend)升序 DESC(descend)降序

就是按照存放的物理顺序建立索引 因为计算机不是按照书的目录那样顺序存储的

聚簇索引会把索引调换成1->C盘 2->E盘那样 也就是把逻辑顺序弄成物理顺序那样

这样方便查找

【例】在Student表的Sname列上建立一个聚簇索引

2. 删除索引

DROP INDEX <索引名>


3.3.4 数据字典

⭐️3.4 数据查询SELECT

distinct是选择列

group by是分组

order by是排序

3.4.1 单表查询 后面分点顺序就是语句中顺序

1. 选择若干列

查询一列或者几列

查询全部列

查询进过计算的值

【例】查询全体学生的姓名及出生年份 今年为2004

SELECT Sname,2004-Sage FROM Student;

**【例】**查询全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名。

【例】 使用列别名改变查询结果的列标题。

别名写在查询列的后面 就代表输出的时候的列名

2. 选择表中的若干元组

(1)消除取值重复的若干行

distinct:有区别的 清晰的 独特的

DISTINCT:去除重复的行

(2)查询满足条件的元组 三段论(查询什么 从什么表中查询 查询的条件是什么)

使用where字句实现 其实就是定语从句

字符匹配 模糊查询

①比较大小

确定范围

BETWEEN AND和NOT BETWEEN AND (not大小写都可以)

③确定集合

IN<值表>,NOT IN<值表>

△④字符匹配

ESCAPE这里类比C语言的转义转义符 //

记得字符要用单引号' ' 数字不用

⑤涉及空值的查询

IS NULL 或IS NOT NULL

IS不能用=代替

不能写成NOT IS

⑥多重条件查询

('IS','MA','CS')这是一个属性组 所以这个括号要这样写

3. ORDER BY字句

ORDER BY子句可以按一个或多个属性列排序:

升序:ASCascend上升 攀升

降序:DESC descend下降

缺省值为升序 当排序含空值时 空值默认最大值

4. 聚集函数 这个放在SELECT与表名之间(作用在查询结果上) !不能用于WHERE字句当中
5.GROUP BY字句 后面可接HAVING作为分组的条件

【例】求各个课程号及相应的选课人数

GROUP BY Cno 就是按课程号分组 再按照分组的结果COUNT() 统计列中元素个数 求出每组人数

【例】查询选修了3门以上课程的学生学号

COUNT(*)的意思是分组组内元素个数大于3的 因为*代表统计元组个数嘛

第二步分组

这里只是分组成这样 不代表一行是一个元组

第四步再筛选

最终结果

sql 复制代码
SELECT Sno 
FROM SC 
GROUP BY Sno 
HAVING COUNT(*) > 3;
严谨来讲这里用COUNT(Sno)>3比(*)要好 因为*包含了NULL值的情况 可能有学号为NULL的

COUNT(*):会统计分组内所有行数 ,哪怕某行 Sno 为空(无效记录),也会被算成 "一门课",导致统计结果失真。

HAVING语句与WHERE语句的区别:

【例】]查询平均成绩大于等于90分的学生学号和平均成绩

什么时候要分组?是先分组 再用函数筛选聚集

就是当对聚集函数设置条件 比如上面的平均成绩大于90的学生 的时候就要进行分组

因为不分组的话 就有两个聚集函数了 而我们的聚集函数只能在SELECT和GROUP BY的字句后面

其次如果不分组就算不报错也会出现逻辑错误 计算的就是所有平均分


3.4.2 连接查询

连接的时候并不会物理生成一个新表 只是连接起来用

1. 等值与非等值连接查询

连接查询的WHERE语句用来连接两个表的条件称为连接条件或连接谓词

就用格式1吧为了避免弄混淆

【注意】

【例】查询每个学生及其选修课程的情况。

自然连接

就是去除重复项

不用全部显示出来就可以 就是不用加*

建议每一列的都加上表名


2. 自身连接

定义:一个表与其自己进行连接

【例】查询每一门课的间接先修课(即先修课的先修课)

先取别名 就是直接在表名的语句后面加别名

再把两个表 FIRST的Cpno和SECOND的Cno自然连接


3. 外连接

前面连接没有连接上的元组 我们叫悬浮元组

把悬浮元组加进来就是外连接

加左边表的叫左连接 右边为右连接

【例】查询每个学生及其选修课程的情况。

这里用的左外连接 因为有的学生有信息 但是没有选课 所以加上学生的信息(即左表的悬浮元组)


4. 多表连接

定义:连接操作时两个以上的表进行连接


3.4.3 嵌套查询(也可以用WHERE来进行连接语句替代 类比定语从句)

【说明】

【例】查询选择了2号课程的学生

1.带有IN谓词的子查询

【例】查询与"刘晨"在同一个系学习的学生。

方法一:

方法二:

【例】查询选修了课程名为"信息系统"的学生学号和姓名

方法二:

【说明】了解

2. 带有比较运算符的子查询

【例】找出每个学生超过他选修课程平均成绩的课程号

这里的SC x和SC y只是起别名 因为要自身连接

这里面子查询相当于是先查询了每个学生的平均值

父查询再在SC里每一个Grade与查询结果比较


3. 带有ANY (SOME)或ALL谓词的子查询

谓词语义:

【例】]查询非计算机科学系中比计算机科学任意一个学生年龄

AND和子查询并列 是父查询里面的 不是子查询里的

谓词<> 等值域谓词 !=

只用找到最大值即可

【例】查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄。

【说明】有一些ANY ALL能用聚集函数替换

4. 带有EXISTS谓词的子查询(存在量词)

EXISTS谓词代表存在量词,带有EXISTS谓词的子查询只返回逻辑真值 "true"或逻辑假值 "false"

【例】查询所有选修了1号课程的学生姓名

这里嵌套查询的意思是

  • 外层查询(父查询)

    sql 复制代码
    SELECT Sname FROM Student

    作用:从学生表(Student)中获取学生姓名(Sname)。

  • 内层查询(子查询)

    sql 复制代码
    SELECT * FROM SC WHERE Sno = Student.Sno AND Cno = '1'

    作用:检查 "当前学生(Student.Sno)是否在选课表(SC)中有'选修 1 号课程(Cno='1')'的记录"。

  • EXISTS的作用WHERE EXISTS (子查询)表示:只要子查询能查到结果(即存在符合条件的记录),就保留当前学生

这个查询是逐行执行 的,对Student表中的每一个学生:

  1. 拿到该学生的学号(Student.Sno);
  2. 在内层子查询中,去SC表找 "学号 = 该学生学号,且课程号 = 1" 的记录;
  3. 如果子查询能找到记录(说明该学生选了 1 号课),EXISTS为 "真",外层查询就返回这个学生的姓名;
  4. 如果子查询找不到记录(说明该学生没选 1 号课),EXISTS为 "假",这个学生不会被返回。

【说明】

区别是第一个要连接成一个大表

第二个是用每一个学生的跟这个学生自己的选课号比较是否为1

嵌套的效率更高 占用空间更小

【例】查询没有选修1号课程的学生名字

这里一样如果选修了1号课程就为假,不返回;不为1就返回

这里不用 EXISTS 然后!=1的原因是: 学生可能还选修了别的课程比如同时选择了1号和2号 也为真 也会返回

所以这里也不能用WHERE ... Cno !=1

如果用连接的做法

sql 复制代码
SELECT DISTINCT Student.Sname
FROM Student
LEFT JOIN SC 
  ON Student.Sno = SC.Sno AND SC.Cno = '1'  -- 只关联"选修1号课"的记录
WHERE SC.Sno IS NULL;  -- 筛选"未匹配到1号课"的学生

【例】

后面的了解

【例】

3.4.4 集合查询

集合查询是对查询结果进行操作

1. 并操作(UNION)

如果没有加ALL 会自动去重

【例】查询选修了一号或者二号课程的学生

2. 交操作 INTERSECT

【例】查询计算机系的学生年龄不大于19岁的学生的交集

【例】

3. 差操作EXCEPT

【例】

3.4.5 基于派生表的查询

就是临时生成的表作为查询对象

AS是给这个表新起名字 后面是新名字与属性集

因为没有聚集函数就没有新生成的属性 没有新的列 所以不用指定

【例】

3.4.6 SELECT语句的基本格式

SELECT [ALL|DISTINCT]

3.5 数据更新

3.5.1 插入数据

1. 插入元组

【例】插入一个新学生元组

下面的如果into的表没有写属性列

会默认 下面的数据每一个一一对应 这时候要求给的值要和表中属性对应

【例】插入选课记录

2. 插入子查询结果

后面接的是子查询

【例】]对每一个系,求学生的平均年龄,并把结果存入数据库。第一步:建表

3.5.2 修改数据UPDATE

3.5.3 删除数据DELETE

3.6 空值的处理

码属性不能为空

UNIQUE不能为空

属性定义中有NOT NULL约束条件的不能取空值

3.7 视图 (虚表)

虚表 是从一个或者几个基本表得到的

数据库只定义 不存放视图的值 这些值来自于基本表

1.视图的特点

2.基于视图的操作

3.7.1 定义视图

1.基于一个基表的视图

AS大概理解成基于···

【例】

【例】

WITH CHECK OPTION会检查完整性保证更新的为满足视图定义的数据

2.基于多个基表的视图

3. 基于视图的视图

4. 带表达式的视图

5.分组视图

6. 不指定属性列的视图

3.7.2.删除视图DROP VIEW <视图名>

【例】

有嵌套的视图删除应该使用CASCADE

3.7.3 查询视图

跟基本表一样 都是用SELECT

【例】

分组的条件应该用HAVING不能用WHERE

3.7.4 更新视图

【例】

【例】

【例】

有一些视图不能更新 因为不能转换为基本表的更新 因为视图不存放数据 是来自于基本表的数据

【例】

3.7.5 视图的作用

相关推荐
尽兴-9 小时前
MySQL执行UPDATE语句的全流程深度解析
数据库·mysql·innodb·dba·存储引擎·update
alonewolf_999 小时前
MySQL 架构与SQL执行全流程深度解析
sql·mysql·架构
MXM_7779 小时前
laravel 并发控制写法-涉及资金
java·数据库·oracle
进阶的小名9 小时前
[超轻量级消息队列(MQ)] Redis 不只是缓存:我用 Redis Stream 实现了一个 MQ(自定义注解方式)
数据库·spring boot·redis·缓存·消息队列·个人开发
列御寇9 小时前
MongoDB分片集群——分片键(Shard Keys)概述
数据库·mongodb
oMcLin9 小时前
如何在Ubuntu 22.04 LTS上通过配置ZFS存储池,提升高吞吐量数据库的读写性能与可靠性?
linux·数据库·ubuntu
Cx330❀9 小时前
脉脉平台深度测评:【AI创作者xAMA】从职场社交到AI创作赋能
数据库·人工智能·脉脉
f***24119 小时前
Bug侦探团:破解技术悬案的秘密武器
数据库
Li_7695329 小时前
Redis 进阶(八)—— 分布式锁
数据库·redis·分布式