一:基本概念
1. SQL的定义
SQL即结构化查询语言,是一种通用的关系数据库的标准语言,包括数据定义、数据操纵、数据查询、数据控制等功能
2. SQL语言的特点
- 综合统一
- 高度非过程化
- 面向集合
- 简洁
3. SQL语言的组成
- DDL
- 数据定义语言:定义、删除、修改关系和视图
- 完整性约束
- DML
- 交互式操纵语言:查询、更新、删除、插入数据
- DCL
- 权限管理
- 事务控制
二:SQL数据定义
1. 约束
(1)单表约束
域完整性
check:对属性域进行条件检查
constarint 约束名 check(比较表达式)
constarint 约束名 check(value in 属性值集合)
unique(候选键完整性):唯一域
constarint 约束名 unique
null:非空约束
constarint 约束名 not null / null
参照完整性(子集约束)
- 插入元组:判断插入的外键是否存在
- 删除元组:判断删除的主键是否被引用,需要发出异常或级联删除
- 更新元组:
- 如果是在参照关系中更新,同样需要判断更新的外键是否存在
- 如果是在被参照关系中更新,同样需要判断更新的主键是否被引用,需要发出异常或级联更新
constarint 约束名 foreign key(参照关系R的属性名,R的外键)
references 被参照关系S(被参照的属性名,S的主键)
on delete cascade 级联删除
on delete set null 设为空值
on delete set default 设为默认值
on update cascade 级联更新
主体完整性
constarint 约束名 primary key(属性名,R的主键)
自定义完整性
域——弱类型(如果基本类型相同,可以互相赋值)
create domain 域名 数据类型
constraint 约束名 约束条件
类型——强类型
create type 类型名 数据类型
constraint 约束名 约束条件
(2)多表约束——断言
create assertion 断言名字 check 条件(利用多表查询)
2. 表与属性
(1)创建表
create table 表名
(
属性名 属性类型 列级完整性约束,
表级完整性约束
);
(2)删除表
drop table 表名;
(3)修改表
增加属性
alter table 表名 add 属性 属性类型 列级约束;
增加表级约束
alter table 表名 add constraint 约束名 约束;
删除属性
alter table 表名 drop 属性;
删除表级约束
alter table 表名 drop 约束名;
修改属性
alter table 表名 modify 属性 属性类型;
3. 视图
(1)视图的定义
通过查询语句定义的“虚关系”,在概念上包含查询结果,不会预先计算并存储,对视图的访问最终会访问物理表。
(2)视图的作用
- 集中数据,满足用户不同的需求
- 保护部分数据,避免用户都能看到整个逻辑模型。
(3)创建视图
create view 视图名V (属性名A1,A2...默认为查询结果的属性)
as
select查询语句(通常无序,可重复)
with check option(对更新操作进行检查);
(4)删除视图
drop view 视图名V;
(5)嵌套视图
create view 视图名V2 (属性名A1,A2...)
as
select查询语句(在视图V1查询);
(6)物化视图
存储视图关系,对视图进行物理化。如果关系R发生改变,则对应的视图V也会发生改变。
- 立即维护:当定义视图的任意关系R发生改变时,视图进行维护
- 延迟维护:当访问视图时才进行维护
- 周期性维护视图:数据过时
4. 索引
(1)索引的定义
关系中的某些属性或属性值→指向对应数据页的逻辑指针
(2)索引的作用
- 用空间换时间
- 加快检索数据
- 加快表与表之间的连接
- 加快查询时的分组和排序
- 创建唯一索引,可保证数据记录的唯一性
(3)索引的分类
- 聚集索引:索引项的顺序与记录的物理顺序一致
- 非聚集索引:索引项的顺序与记录的物理顺序不一定相同
(4)建立索引
间接创建索引
定义主键约束或者唯一约束,可以间接创建索引
直接创建索引
单个索引
普通索引
create index 索引名I
on 表名R(属性A1)
唯一索引(属性值不会相同)
create unique index 索引名I
on 表名R(属性A)
聚集索引(顺序不会改变)
create cluster index 索引名I
on 表名R(属性A)
复合索引
create index 索引名I
on 表名R(属性列表A1 asc,A2 desc...)
(5)删除索引
drop index 索引名I
三:SQL数据操作
1. 查询数据
(1)基本查询
SQL语句:
select 属性A1,A2...
from 表名 R
where 条件P
相当于关系代数(多重集版本):ΠA1,A2…(σP( R))
p:选择谓词
- 算术比较符
- 逻辑运算符
- 集合运算: in,not in,>some,>all,<some,<all
- 空值比较:is null,is not null
- 字符串匹配:like
算术表达式(广义投影)
SQL语句:
select 属性A+算术表达式...
from 表名 R1,R2...
where 条件P
相当于关系代数:Π算术表达式…(σP( R1,R2… ))
多表查询(自然连接)
SQL语句:
select 属性A1,A2...
from 表名 R1,R2
where 条件P and R1.A = R2.A
相当于关系代数:ΠA1,A2…(σP( R1⋈R2))
选择所有属性
select *
from 表名 R1,R2...
where 条件P
去除重复
select distinct 属性A1,A2...
from 表名 R1,R2...
where 条件P
重命名
重命名属性
select 属性A1 as B1,A2...
from 表名 R1,R2
where 条件P and R1.A = R2.A
重命名关系
select 属性R.A1,S.A2...
from 表名 R1 as R,R2 as S
where 条件P and R.A = S.A
自表查询——重命名关系(便于区分)
select 属性R1.A1,R2.A2...
from 表名 R as R1,R as R2
where 条件P and R1.A = R2.A
字符串模式匹配
like + 通配符:
- %:匹配任意子串
- XX%:匹配开头是XX的字符串
- %XX:匹配结尾是XX的字符串
- %XX%:匹配包含XX的字符串
- _:匹配任意一个字符
(如果需要转义,使用 转化符 + 通配符,用escape定义转化符)
select 属性R1.A1,R2.A2...
from 表名 R
where A like 模式串escape 转化符
排序
- asc:升序
- desc:降序
select 属性R1.A1,R2.A2...
from 表名 R
where 条件P
order by 排序的字段A1 asc,A2 desc
(2)聚集查询
聚集函数(忽略null):
- avg:平均值
- min:最小值
- max:最大值
- sum:值的总和
- count:值的数量
分组函数(把null当做一般的值):
(没有出现在group by 子句中的属性,如果出现在select子句或者having子句中,只能出现在聚集函数内部)
select 目标属性A(不能出现其他属性),分组函数(属性B) as 目标属性B‘
from 表名 R
where 条件P
group by 分组属性 A
having 分组后的选择条件(属性C)
order by 排序属性A
(3)查询结果之间的集合运算
默认为不可重复
- R union S
- R intersect S
- R except S
保留重复:如果元组在R中重复出现m次,在S中重复出现n次
- R union all S:m+n
- R intersect all S:min(m,n)
- R except all S:max(0,m-n)
(4)查询之间的嵌套
子查询是嵌套在另一个查询中的查询语句
- 嵌套子查询:只执行一次。
- 先执行子查询
- 再将结果传递给外部查询使用
- 相关子查询:引用了外部属性,执行多次。
- 先执行外部查询,获取元组
- 将元组传递给子查询
- 执行子查询
- 将结果传递给外部查询使用
where + 嵌套:约束条件
匹配拥有集合特定属性值的元组
- 属于某个集合的元组:in
- 不属于某个集合的元组: not in
select 目标属性A2,A3...
from 表名R
where 匹配属性A1,A2... in
(select 匹配属性A1,A2...
from 表名R
where 条件P)
比较元组和特定集合所有元组的属性值(使用子查询+聚集函数的效率更高)
比较关键字
- some/any(至少一个)
- 至少比集合的某个元素大:>some
- 至少比集合的某个元素小:<some
- 至少和集合的某个元素相同(in):=some
- 至少和集合的某个元素不同:<>some
- all(全部)
- 比集合的全部元素大:>all
- 比集合的全部元素小:<all
- 和集合的全部元素相同:=all
- 和集合的全部元素不同(not in):<>all
select 目标属性A2,A3...
from 表名R
where 匹配属性A1 比较关键字
(select 匹配属性A1
from 表名R
where 条件P)
测试集合是否为空,元组的是否满足某个条件
- exists:集合为非空集
- not exists:集合为空集
- X- Y = 空集,也就是X包含于Y
select 目标属性R1.A2,R1.A3...
from 表名 R as R1
where exists
(select 匹配属性R2.A1,R2.A2...
from 表名R as R2
where R1.XX = R2.XX)
测试集合是否有重复元组
- unique:子查询没有重复元组(最多一个)
- not unique:子查询有重复元组(最少两个)
select 目标属性A2,A3...
from 表名 R as R1
where unique
(select 匹配属性R2.A1,R2.A2...
from 表名R as R2
where R1.XX = R2.XX)
from+ 嵌套:构建局部视图
select 临时属性A2,A3...
from
(select 属性A1,A2,A3...
from 表名R
where 条件P)
as 临时表名X(临时属性A1,A2,A3)
where 条件P
也可以使用with子句
with 临时表名X(临时属性A1,A2,A3) as
(select 属性A1,A2,A3...
from 表名R
where 条件P) ,临时表Y...
select 临时属性A2,A3...
from 临时表X
where 条件P
(5)顺序
- from
- where
- group
- having
- select
- order by
2. 修改数据
(1)删除元组
普通删除
delete from 表R
where 条件P;
结合查询
delete from 表R
where select子查询语句;
(2)插入元组
普通插入
insert into 表R(属性名A1,A2...默认全部属性)
values(‘属性值V1’,V2...);
结合查询
insert into 表R(属性名A1,A2...默认全部属性)
select子查询语句;
插入视图
条件:
- from子句只涉及一个关系R
- select子句只包含属性名,不包含算术表达式、聚集函数、distinct关键字
- 任何没有出现在select子句的属性可以为空(即属性没有主键约束和非空约束)
- 查询子句不含有聚集操作
insert into 视图名V
values(属性值V1,V2...如果没有对应默认为空);
(3)更新元组和属性
普通更新,单条件
update 表R
set 属性名A1 = ‘属性值V1’,A2 = V2...
where 条件P;
结合查询,单条件
update 表R
set 属性名A1 = ‘属性值V1’,A2 = V2...
where select子查询语句;
多条件,避免顺序问题,使用case语句
update 表R
set 属性名A = case
when 条件P1 then 属性值V1
when 条件P2 then 属性值V2
else 属性值V3
end
3. 数据控制SQL
(1)权限内容:
- 属性列/视图 TABLE
- 读取数据 select
- 插入数据 insert
- 修改数据 update
- 删除数据 delete
- 所有权限 all privileges
- 基本表 TABLE
- 读取数据 select
- 插入数据 insert
- 修改数据 update
- 删除数据 delete
- 修改表 alter
- 索引 index
- 所有权限 all privileges
- 数据库 DATABASE
- 建表权限 createtab
- 外键约束 reference
权限与视图:
视图可以把部分数据授权给用户,而不需要把涉及的关系的所有数据授权给用户
作用:隐藏数据,增加安全性
(2)用户内容
- 所有用户:public
- 指定用户:
- 用户ID
- 角色
用户与角色
通过角色可以指定一类用户的共同权限
创建角色
create role 角色名R
赋予角色
grant 角色名R to 用户名
grant 角色名R1 to 另一角色名R2
(3)授予权限与收回权限
表示:授权图
- 节点:用户
- 根节点:数据库管理员DBA
- 边:用户A将权限授予给用户B
授权:
授权的边必须是从根节点root出发的路径的一部分
grant 权限列表
on 授权对象 授权对象名
to 用户列表
with grant option(允许转授权限)
收权:
- 级联回收:如果收权的节点还有一条唯一指向其他节点的边,那么这条边也被收回
- 如果用户有被其他用户授权权限,则可能仍然具有该权限
revoke 权限列表
on 授权对象 授权对象名
from 用户列表
cascade (级联回收)
restrict(阻止级联回收)