数据库基础
数据抽象的过程
基本的逻辑模型类型
- 层次模型:树状结构
- 网状模型:有向图
- 关系模型:二维表格表达实体集(ER模型就是一种关系模型)
- 对象模型:面向对象编程(类和对象的概念)
常用词语及其缩写
数据操纵语言(Data Manipulation Language,DML)
数据库(DataBase,DB)
数据库系统(DataBase System,DBS)
数据库管理系统(DataBase Management System,DBMS)
数据定义语言(Data Definition Language,DDL)
操作系统(Operation System,OS)
数据库系统的组成
- 数据库
- 硬件
- 软件
- 数据库管理员
数据库系统层次
ER图(实体联系模型Entity Relationship Model)
3个基本成分:
- 矩形:表示实体类型(即对象)
- 菱形:表示联系类型(即实体间联系)
- 椭圆形:表示实体类型和联系类型的属性(即属性)
3种联系的类型:
- 1:1(一对一;外键放哪边都行)
- 1:N(一对多;外键放多的那边)
- M:N(多对多;单独建表,新表的主键是有两个表的主键组成的并集)
关系模型和关系运算理论
注意:关系=表
注意:模式=表的集合
键:用于唯一标识一行元组(记录)的属性(字段)。
键的分类:
- 超键:用于唯一标识一行元组(记录)的一个或多个属性(字段)组成的集合。
- 候选键:没有冗余属性的超键。
- 主键:被用户从候选键中选出来作为真正使用的键。
- 外键:一个关系模式(表)A中的某个属性同时是另外一个关系模式(表)B中的主键,则称这个属性为关系模式(表)A的外键。
为了直观,用图表示他们之间的关系
关系的定义和属性
关系:一个属性数目相同的元组组成的集合。
规范性限制:
- 关系中的每一个属性都是不可分解的,即表中无表,这也是“第一范式”。
- 元组不重复
- 无行序
- 无列序
关系模型的3种完整性规则
- 实体完整性规则(Entity Integrity Rule):主键不空
- 参照完整性规则(Reference Integrity Rule):1.外键可与相应的主键不同名。2.外键可以用于建立一个表和自身的联系,即此时这个表的外键和主键是同一个属性。3.外键是否可以为NULL应当视具体情况而定。
- 用户定义的完整性规则
关系模型的3层体系结构
- 关系模式:表,逻辑存储结构,是存储模式在逻辑层面的描述。
- 子模式:用户所使用的那部分数据及组成的表。(查询结果视图)
- 存储模式:数据以文件形式存储在底层,存储的实际模式就是存储模式。
关系运算(重点!!!)
DML分为:1.查询语句:
-
关系代数:查询操作是以集合操作为基础的运算。
-
关系演算:查询操作是以谓词演算为基础的运算。
-
关系逻辑:查询操作是以if-then逻辑操作为基础的运算。
2.更新语句: -
插入
-
修改
-
删除
关系代数的五个基本操作:
- 并(Union):两个表的属性集合之间求并集,这里指的是内部并,即两个表的属性完全一致。
- 差(Difference):两个表的属性集合之间求差集
- 笛卡尔积(Cartesian Product):两个表的元组之间穷举拼接,也叫叉乘
- 投影(Projection):竖切属性集。表示如下
- 选择(Selection):横选部分行,也叫横切。表示如下
关系代数的四个组合操作:
组合操作都可以通过有限个基本操作实现,即“基本操作的组合”。
-
交(Intersection):两个表的属性集合之间求交集
-
连接(Join):叉乘+约束条件(比如要求某两列属性之间相等或满足某种关系)
表示R与S连接,条件是R的第2列和S的第1列中值相等的那些元组(行,也叫记录)进行连接。 -
自然连接(Natural Join):叉乘+约束条件(相同的属性集上的值相等的行才能拼接)+去掉重复属性
-
除法(Division):表A除以表B(前提是表A中包含了表B的所有属性),其实是,在表A中寻找某个对象满足表B的所有行,把这些对象并成一张表就是除法的结果,这其中不用写出表B的属性。
图和对应的关系代数语言
关系代数的七个扩充操作:
-
改名
将表R中的列名依次改为A1,A2,… -
广义投影:允许在投影列表中使用算术函数来对投影进行扩展。
-
赋值
-
外连接:在自然连接的基础上,将不满足连接条件的行补上,缺失值的地方就写null。
-
外部并:将两个表的属性求并集,公共属性只取一次,不同属性处的空值赋null。
-
半连接:R和S进行自然连接,若是左办连接,则结果为R中满足自然连接的元组构成的表;若为右办连接则结果为S中满足自然连接的元组构成的表。
-
聚集操作:输入一组值,输出一个值作为结果的操作。例如,max,min,avg,sum,count等等。
关系代数表达式的优化
优化原则:
- 投影尽早进行
- 先投影再选择,选择也要尽早进行。
- 前两个要求都要注意,保留后续操作还需要用到的属性或元组。
- 尽量减少操作中多个表的连接,因为多表连接操作代价昂贵。
数据库规范化设计
关系模式的非形式化设计准则
- 一个表中尽量只包含跟这个表中每个元组所表示的对象有直接联系的属性,尽量不包含间接联系的属性。
- 关系模式(库)的设计应尽可能使得相应的关系(表)之间不发生增删改查的异常,如有异常则应进行相应的说明,以确保数据库操作的正确性。
- 表中尽量避免经常为null值的属性出现。
- 表和表之间的等值连接尽量在主键和外键上进行,且保证连接以后不会产生额外的元组(寄生元组)。
函数依赖(Function Dependency, FD)
函数依赖:一个表中的属性a可以确定其他的某个或某些属性,这种关系成为函数依赖。(1对1或多对1;即不同的a的值可以对应同样的某些属性的值,但反过来不行。)
FD的逻辑蕴含:在一个关系模式P(库)中,存在一个FD集合F,f是一个函数依赖,若对P中所有的关系(表),满足F的表都满足f,则称F逻辑蕴含f。(即f属于F,前提是只需在当前这个库P中属于就行,相当于放宽了数学上的属于条件)
FD的闭包:在一个关系模式P(库)中,FD集合F的所有子集构成的集合称为F的闭包。记作
FD的推理规则:
- 自反性
- 增广性
- 传递性
- 合并性
- 分解性
- 伪传递性
- 复合性
- 其他
平凡:当属性集A确定,且a是A中的一个属性,那么a属性也确定了,这是自然而然的,所以是平凡的函数依赖,即平凡的FD。否则就是非平凡的FD。
FD的最小依赖集G:
- G中的每个FD的右边都是单属性(右单)
- G中的每个FD的左边都没有冗余属性(左不冗余)
- G中没有冗余的FD(FD不冗余)
关系模式的分解
模式分解的问题
- 寄生元组:有泛关系,拆分导致重新合并时元组变多了。
- 悬挂元组:无泛关系,合并导致元组变少。
无损分解(分解后再合并仍旧能恢复到和原来一样,即不损失信息。)
保持函数依赖的有损分解(分解后再合并不能恢复到和原来一样,即损失信息。)
关系模式的范式
- 第一范式(1NF):表中无表
- 第二范式(2NF):主键不冗余(不存在局部依赖)
- 第三范式(3NF):主键不能通过传递依赖确定自己当中的一部分。
传递依赖:如果X->Y且Y->A,同时,第一步不能反推,第二步不是平凡的,则称A传递依赖于X。
事务
事务:一堆操作按照一定顺序排列成的序列,这个序列作为一个整体,其中的操作要么都执行,要么都不执行。
事务的调度方式
- 串行:一个一个的按照顺序执行,在cpu中同时只有一个事务在执行。
- 并行:多个事务同时执行,在cpu中同时可以有多个事务在执行。
- 并发:将多个事务拆分成一个一个的子任务,然后按照时间片,一个子任务一个子任务的执行,给用户感觉好像多个事务是在同时执行一样,而实际上,这就是子任务的串行。(所谓“假并行,真串行,就是并发。”)
事务的ACID性质:
- 原子性:事务作为一个整体,不可分割的执行单元。
- 一致性:数据不会因事务的执行而遭到破坏。
- 隔离性:多个事务并发执行的结果应与这些事务先后单独执行(串行)的结果一样。
- 持久性:一个事务一旦完成执行,其结果应当永久的反映在数据库中。
事务的状态变迁图
故障检查(检查点技术)
- undo:事务未做完,出故障。(对应ROOLBACK语句)因为故障可能就是由这样的事务引起的,故undo。
- redo:事务做完了,但是结果还在缓冲区,尚未完全写入磁盘,出故障。因为故障一般不会是这样的事务引起的,故redo。
数据库的并发控制
并发操作带来的3个问题
- 丢失更新:对同一个位置,一个事务的执行结果,被另一个事务的执行结果覆盖。(多次写入同一个位置)
- 读脏数据:一个事务读取了另一个事务的错误结果。
- 不可重复读:一个事务读取了另一个事务的中间结果。
封锁技术
- 排他型封锁(X锁):可读可写,只能同时由一个事务单独调用。
- 共享型封锁(S锁):只读不写,可以同时由多个事务一起调用。
死锁问题
SQL入门
注意:1.SQL语句结尾又分号“;”。2.SQL语句中不区分大小写。3.[]表示可选项,|表示或。
模式创建和撤销(建库和删库)
CREATE SCHEMA <模式名> AUTHORIZATION 用户名;
例如
create schema ST_CO authorization lismith;
DROP SCHEMA <模式名> [CASCADE | RESTRICT]
CASCADE 强制全部删除(级联式)
RESTRICT 没有被其他模式引用的部分则删除,否则不执行(安全删除)(约束式)
例如
drop schema ST_CO cascade;
基本数据类型
关键字 | 意义 |
---|---|
INTEGER | 长整数(也可写成INT),长度为4B |
SMALLINT | 短整数,长度为2B |
REAL | 浮点数 |
DOUBLE PRECISION | 双精度浮点数 |
FLOAT(n) | 浮点数,至少为n位数字 |
NUMERIC(p,d) | 定点数,由p位数字(不包括符号、小数点)组成,小数点后面有d位数字,也可写成DECIMAL(p,d)或DEC(p,d) |
CHAR(n) | 长度为n的定长字符串 |
VARCHAR(n) | 最大长度为n的变长字符串 |
BIT(n) | 长度为n的二进制串 |
BIT VARYING(n) | 最大长度为n的变长二进制串 |
DATE | 日期,包含年、月、日,形为YYYY-MM-DD |
TIME | 时间,包含一天的时、分、秒,形为HH: MM: SS |
定义新的数据类型
CREATE DOMAIN <新数据类型名> <基本数据类型>;
例如
create domain P char(8);
关系的基本操作(表的基本操作)
- 创建
- 修改
- 撤销
创建
CREATE TABLE <表名>
(<列名 类型>,
<列名 类型>,
…
<完整性约束>
);
例如
create table T
(T# char(4) not null,
tname char(8) not null,
title char(10),
C## char(6) not null,
primary key(T#),
foreign key(C##) reference C(C#)
);
修改
增加列
ALTER TABLE <表名> ADD <列名> <类型>;
删除列
ALTER TABLE <表名> DROP <列名> <类型>;
修改列
ALTER TABLE <表名> MODIFY <列名> <类型>;
或
ALTER TABLE <表名> ALTER COLUME <列名> <类型>; (现在这种更常用)
撤销
DROP TABLE <表名> [CASCADE | RESTRICT];
索引的基本操作
- 创建
- 撤销
创建
CREATE [UNIQUE] INDEX <索引名> ON <表名> (<列名序列>)
例如
create unique index S#_INDEX on S(S#);
撤销
DROP INDEX <索引名>
例如
drop index S#_INDEX;
数据的基本操作(增删改查)
数据查询
SELECT [ALL | DISTINCT] <投影属性序列或表达式序列>
FROM <表序列或视图序列>
[WHERE <行条件表达式>]
[GROUP BY <列名序列>
[HAVING <组条件表达式>]]
[ORDER BY <列名[ASC | DESC]>,…];
ALL表示select结果返回所有非空行(包含重复的行),DISTINCT表示select结果返回所有不重复的非空行。其中ALL是默认值,可不写出。
ASC表示升序,DESC表示降序。
例如
select S#, C#, SCORE, SNAME, CNAME
from S,C,SC
where S.S#=SC.S# and C.C#=SC.C#
group by S#,C#
having SCORE>60
order by DESC;
from后面多个表之间用’,'表示笛卡尔积
数据增加(插入)
1.单元组插入(当插入的元组和全部列名一一对应,则可以省略写出列名序列)
INSERT INTO <表名> [(列名序列)]
VALUES(<元组值>);
2.多元组插入
INSERT INTO <表名> [(列名序列)]
VALUES(<元组值>),(<元组值>),…;
3.查询结果插入
INSERT INTO <表名> [(列名序列)]
<SELECT 查询语句>;
4.表的插入
INSERT INTO <表名1> [(列名序列)]
TABLE <表名2>;
例如
insert into SC
values(‘S4’,‘C4’,85),
(‘S3’,‘C6’,90),
(‘S7’,‘C2’,70);
数据删除
DELETE FROM <表名>
[WHERE <条件表达式>];
例如
delete from SC
where C# = ‘C4’ and
SCORE < (select avg(SCORE)
from SC
where C# = ‘C4’);
数据修改
UPDATE <表名>
SET <列名> = <值表达式> [,<列名> = <值表达式>…] | ROW = (<元组>)
[WHERE <条件表达式>];
例如
update SC
set SCORE = SCORE * 1.3
where C# = ‘C4’;
WHERE中可使用的运算符表
运算符类别 | 运算符 |
---|---|
算数比较运算符 | <, <=, >, >=, =, <> 或 != |
逻辑运算符 | AND, OR, NOT |
集合成员资格运算符 | IN, NOT IN |
谓词 | EXISTS(存在量词), ALL, SOME, ANY, BETWEEN … AND …, UNIQUE, LIKE, IS |
聚合函数 | AVG(平均值), MIN(最小值), MAX(最大值), SUM(和), COUNT(计数) |
算数比较运算符 | <, <=, >, >=, =, <> 或 != |
注意:1.WHERE的条件部分也可以是内层查询语句,即SELECT语句可嵌套。2.SELECT语句可以表达所有的关系代数表达式。3.SELECT语句的查询结果之间还可以进行集合运算。
运算符类别 | 运算符 |
---|---|
集合运算符 | UNION(并), INTERSECT(交), EXCEPT(差) |
嵌套查询的例子
select S#, SNAME
from S
where ‘C2’ in (
select C#
from SC
where S# = S.S#
);
字符串匹配查询
匹配表达式:
- 百分号(%)表示与零个或多个字符组成的字符串匹配。
- 下划线(_)表示与单个字符串匹配。
例1
select SNAME
from S
where SNAME like ‘D%’;
查询名字以字母D开头的学生姓名。
例2 空字符串匹配用‘is’
select SNAME
from S
where AGE is null;
表的基本连接操作
连接类型 | 关键字 |
---|---|
内连接 | INNER JOIN |
左外连接 | LEFT OUTER JOIN |
右外连接 | RIGHT OUTER JOIN |
完全外连接 | FULL OUTER JOIN |
连接条件(写在连接类型的右边) | 关键字 |
---|---|
自然连接 | NATURAL |
等值连接 | ON |
部分公共属性连接 | USING |
例如
E1: R natural left outer join S;
E2: R left outer join S on R.B = S.B and R.C = S.C;
E3: R left outer join S using (B)
视图
- 创建
- 撤销
- 更新
视图创建
CREATE VIEW <视图名> (<列名序列>)
AS <SELECT 查询语句>;
例如
create view S_NAME
as select S#,SNAME,AGE
from S
where SEX = ‘M’;
视图撤销
DROP VIEW <视图名>;
drop view S_NAME;
视图更新
只有“行列子视图”可以进行视图更新操作。
行列子视图:通过对一张表进行有限次的投影和选择得到的包含了主键的视图,称为行列子视图。
对行列子视图的更新会自动转化为对对应的表的更新。
但是,如果要允许用户对一个视图进行更新操作,必须在定义这个视图时加上“WITH CHECK OPTION”语句,当然,这句话不写的情况下默认就是写了的,这相当于将检查过程交给编译器去做。
例如
create view S_NAME
as select S#,SNAME,AGE
from S
where SEX = ‘M’
[with check option];
insert into S_SNAME
values(‘S28’,‘WU’,18,‘M’);
这句插入语句会由系统自动转换为
insert into S
values(‘S28’,‘WU’,18,‘M’);
SQL进阶
局部变量的定义和赋值
局部变量声明
DECLARE{@ 变量名 数据类型 ....}
局部变量赋值SET 变量名=值
或者用select语句进行赋值
SELECT @ 变量名 = expression [from ... where ...]
全局变量
用@@ 变量名 数据类型
流程控制
使用BEGIN {...} END
语句块
条件语句
IF <条件表达式>
{命令行|程序块}
ELSE
{命令行|程序块}
或者
WHEN <条件表达式> THEN
{命令行|程序块}
ELSE
{命令行|程序块}
CASE语句(即SWITCH)
CASE <条件表达式>
WHEN 布尔表达式 THEN {命令行|程序块}
...
END
循环语句
WHEN <条件表达式>
{命令行|程序块}
END
游标
声明游标
DECLARE 游标名 CURSOR
[LOCAL|GLOBAL]
[FORWARD_ONLY|SCROLL]
[STATIC|KEYSET|DYNAMIC|FAST_FORWARD]
[READ_ONLY|SCROLL_LOCKS|OPTIMISTIC]
[TYPE_WARNING]
FOR select语句
[FOR UPDATE[OF 列名[,...n]]]
关键字 | 含义 |
---|---|
LOCAL | 定义游标的作用域仅限于批处理、存储过程或触发器中。当建立游标在存储过程执行结束后,游标会被自动释放。 |
GLOBAL | $12 |
FORWARD_ONLY | $1 |
SCROLL | $1 |
STATIC | $1 |
KEYSET | $1 |
DYNAMIC | $1 |
FAST_FORWARD | $1 |
READ_ONLY | $1 |
SCROLL_LOCKS | $1 |
OPTIMISTIC | $1 |
TYPE_WARNING | $1 |