描述事物的符号记录,数据与其语义是不可分的。
数据库是长期存储在计算机内、有组织的、可共享的长期存储大量数据的集合。
数据库中数据基本特点:永久存储、有组织和可共享三个基本特点。数据库中数据都是按照某一种数据模型来组织、描述和存储的。数据独立性高。
科学地组织和存储数据,高效的获取和维护数据。
是位于用户和操作系统之间的一层数据管理软件
主要功能:
数据库系统是由数据库DB、数据库管理系统DBMS(及其应用开发工具)、应用程序和数据库管理员组成的存储、管理、处理和维护数据的系统
对数据进行分类、组织、编码、存储、检索和维护,它是数据处理的中心问题。数据处理是指对各种数据进行收集、存储、加工和传播的一系列活动的总和。
人工管理阶段、文件系统阶段、数据库系统阶段
特点 | 人工管理阶段 | 文件系统阶段 | 数据库系统阶段 |
---|---|---|---|
管理者 | 程序员 | 文件系统 | 数据库管理系统 |
数据面向对象 | 某一应用程序 | 某一应用 | 部门企业 |
数据的共享程度 | 无共享,冗余度极大 | 共享性差,冗余度答 | 共享性高,冗余度低 |
数据独立性 | 不独立 | 独立性差 | 具有高度的物理独立性和一定的逻辑独立性 |
数据结构化 | 无结构 | 记录内有结构、整体无结构 | 整体结构化,用数据模型描述 |
数据控制能力 | 应用程序自己控制 | 应用程序自己控制 | DBMS提供数据安全性、完整性、并发控制和恢复能力 |
数据结构化(与文件系统的本质区别)
共享性高,冗余度低且易扩展
数据独立性高(独立性指应用程序与逻辑结构、物理存储相互独立)
不会因为系统数据存储结构与数据逻辑结构的变化而影响应用程序
数据统一管理和控制
数据的安全性保护,数据的完整性检查,并发控制和数据库的恢复
数据模型是数据库用来对现实世界进行抽象的的工具,是数据库中用于提供信息表示和操作手段的形式框架
数据模型的数据库系统的核心和基础
表示方法,实体-联系方法,该方法用E-R 图来描述现实世界的概念模型,E-R方法也称为E-R 模型
实体
客观存在并可相互区别的事务称为实体(人、物)
属性
实体所具有的某一特性称为属性
码
唯一标识实体的属性集称为码
实体型
用实体名及其属性集合来抽象和刻画同类实体,称为实体性
实体集
同一类型实体的集合称为实体集
联系
实体之间的联系通常是指不同实体集之间的联系
数据结构
描述数据库的组成对象以及对象之间的联系
数据操作(增删改查)
数据操作是指对数据库中各种对象型的实例值允许执行的操作的几个,包括操作及有关的操作规则
数据的完整性约束条件
数据的完整性约束是一族完整性的规则
像一颗倒立的树,结点的双亲是唯一的
有且只有一个结点没有双亲结点,这个结点称为根结点
根以外的其他结点有且只有一个双亲结点两个条件的记录以及它们之间联系的集合为层次模型
优点:
缺点:
典型的代表是DBTG 系统
特点
优点:
缺点:
特点
优点:
缺点:
存取路径隐蔽,导致查询效率不高,为了提升性能,DMBS必须对用户查询请求进行优化
模式是数据库中全体数据的逻辑结构和特征的描述,它仅仅涉及型(type)的描述,不涉及具体的值。模式的一个具体值称为模式的一个实例。
模式、外模式、内模式
模式也称逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图
外模式也称用户模式,它是数据库用户能够看见和使用的局部数据的逻辑结构和特征的描述。是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。
一个数据库可以有多个外模式。即使对模式中的同一种数据,在外模式的结构中,类型,长度,保密级别都可以不同
也称存储模式,一个数据库只有一个内模式。它是数据物理结构和存储方式的描述,是数据在数据库内部的组织方式。
索引的组织方式
B+树,Bitmap,Hash
记录的存储方式
顺序存储,堆存储,按hash 方法存储
数据是否压缩、数据是否加密
数据存储记录的规定——数据的长度
在数据库系统中,通常用三级模式来描述数据库,其中外模式是用户与数据库的接口,是应用程序可见到的数据描述,概念模式是对数据整体的逻辑结构的描述,而内模式描述了数据的物理结构
外模式/模式映像
模式改变,对映象做修改,可以保证外模式不变,保证了逻辑独立性。
保证数据的逻辑独立性
当模式改变时,数据库管理员对外模式/模式映像作相应改变,使外模式保持不变
应用程序是依据数据的外模式编写的,应用程序不必修改与程序的逻辑独立性,简称数据的逻辑独立性
有一个外模式/模式映像定义外模式与模式之间的对应关系,映像定义通常包含在个外模式的描述中
模式/内模式映象
内模式改变(数据库的存储结构改变),对映象做修改,可以保持模式不变,保证了物理独立性。
按照数据模型三要素,关系模型由数据结构、关系操作集合和关系完整性约束三部分组成
acid 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability).
关系模型的数据结构非常简单,只包含单一的数据结构——关系
关系是关系模式某一时刻的内容或状态
关系在域上D笛卡尔积的子集
关系可以有三种类型:基本关系(基本表)、查询表、试图表。
域
域是一组具有相同数据类型的值的集合
笛卡尔积
给定一组域 D 1 , D 2 , D 3 , D n 的笛卡尔积为 D 1 ∗ D 2 ∗ D 3 = { d 1 , d 2 , d n } 给定一组域D_1,D_2,D_3,D_n的笛卡尔积为D_1*D_2*D_3=\{d_1,d_2,d_n\} 给定一组域D1,D2,D3,Dn的笛卡尔积为D1∗D2∗D3={d1,d2,dn}
每一个元素 ( d 1 , d 2 , d 3 ) 叫做一个元组,每一个元素中的每一个值 d i 叫做一个分量 (d_1,d_2,d_3)叫做一个元组,每一个元素中的每一个值d_i叫做一个分量 (d1,d2,d3)叫做一个元组,每一个元素中的每一个值di叫做一个分量
一个域允许的不同取值个数称为这个域的基数
有6 条性质
关系的描述称为关系模式 ,可形式化的表示为R(U,D,DOM,F)
其中R为关系名,U为组成该关系的属性名集合,D为U中属性所来自的域,DOM为属性向域的映象集合,F为属性间数据的依赖关系集合。
组成部分
关系数据库:关系数据库也有型和值之分,型是关系模式,是对关系数据库的描述。值是关系模式在某一时刻对应的关系集合。
区别
关系模式是型;关系是值,是关系模式的实例。
例如S(num,name,age)是关系模式,组成的表是关系,即某一时刻关系模式的值
在数据库学科中可以把关系模式理解为表的结构、属性之间的关系、约束条件,把关系理解为二维表
查询操作: 选择、投影、连接、除、并、差、交、笛卡尔积
选择、投影、并、差、笛卡尔积是五种基本操作
数据更新:插入、删除、修改
关系代数是用关系的运算来表达查询要求,代表:ISBL;
关系演算语言用谓词来表达查询要求;关系演算又可按照谓词变元的基本对象是元组变量还是域系变量分为元组关系演算和域关系演算
具有关系代数和关系演算双重特点的语言;
代表:SQL(Structured Query Language) ;
若属性A是基本关系R的主属性,则属性A不能取空值
外码
,即该码是另一个表的主码。参照关系
(Referencing Relation),即本表。被参照关系
(Referenced Relation) 或目标关系
(Target Relation),即外码对应的主码所在的表。若属性F是基本关系R的外码,它与基本关系S的主码K相对应,则对R中的每个元组在F上的值,必须为空值或者S中某个元组的主码值
若属性(或属性组)F是基本关系R的外码它与基本关系S的主码Ks相对应(基本关系R和S不一定是不同的关系),则对于R中每个元组在F上的值必须为:
关系代数运算是以集合运算为基础的运算
举例
举例
R和S 具有相同的元数,且对应的属性的类型也相同
下面是RxS的结果,R和S使用上图中的R,S
即属于R又属于S的元组(行)组成
举例
选择出满足条件的元组的操作叫做选择
选择A2值为a或b的元祖
关系R上的投影是从R上选择出若干属性列出组成新的关系
连接也被 θ 连接,它是从两个关系的笛卡尔积中选取属性满足一定条件的元组 连接也被\theta 连接,它是从两个关系的笛卡尔积中选取属性满足一定条件的元组 连接也被θ连接,它是从两个关系的笛卡尔积中选取属性满足一定条件的元组
连接运算中有两种最重要也是最为常用的连接,一种是等值连接,一种是自然连接
θ 为 " = " 的连接运算称为等值连接 \theta 为"=" 的连接运算称为等值连接 θ为"="的连接运算称为等值连接
从广义笛卡尔积中选取A,B 属性值相等的那些元组
自然连接是一种特殊的等值连接
要求两个关系中进行比较的分量必须是同名的属性,且在结果中把重复的属性列去掉
设关系R除以关系S的结果为关系T,则T包含所有在R但不在S上的属性及其值,且T的元组与S的元组的所有组合都在R中
① 综合统一
② 高度非过程化
③ 面向集合的操作方式
④ 以同一种语法结构提供多种使用方式
⑤ 语言简洁,易学易用
SQL功能 | 动词 |
---|---|
数据查询 | SELECT |
数据定义 | CREATE、DROP、ALTER |
数据操纵 | INSERT、UPDATE、DELETE |
数据控制 | GRANT、REVOKE |
存储文件
视图
数据字典
是关系数据库管理系统内部
的一组系统表
,它记录了数据库中所有的定义信息,包括关系模式定义、视图定义、索引定义、完整性约束定义、各类用户对数据库的操作权限、统计信息等
。没有那种数据库支持所有的sql和特性
SQL的数据定义功能: 模式定义
、表定义
、视图
和索引
的定义
定义模式实际上定义了一个命名空间
空间
中可以定义
该模式
包含的数据库对象
,例如基本表
、视图
、索引
等。CREATE SCHEMA <模式名> AUTHORIZATION <用户名>[<表定义子句>|<视图定义子句>|<授权定义子句>]
dbo database owner 数据库的创建者,创建该对象的用户. guest 顾客 能够访问数据库中对象的数据, 要求dbo分配权限给guest, 一般给他查看的权限select
[例1]定义一个学生-课程模式S-T
CREATE SCHEMA "S-T" AUTHORIZATION BitHachi; -- 为用户BitHachi定义了一个模式S-T
CREATE SCHEMA AUTHORIZATION BitHachi;-- <模式名>隐含为用户名BitHachi 这个不知道咋回事,没出结果,默认模式BitHachi没创建出来,没显示
[例2]为用户BitHachi创建了一个模式S-T,并在其中定义了一个表TAB1。
CREATE SCHEMA "S-T" AUTHORIZATION BitHachi
CREATE TABLE TAB1(
COL1 SMALLINT,
COL2 INT,
COL3 CHAR(20),
COL4 NUMERIC(10,3),
COL5 DECIMAL(5,2)
);
DROP SCHEMA <模式名>
CASCADE(级联)
RESTRICT(限制)
DROP SCHEMA "S-T" CASCADE;
DROP SCHEMA "S-T" RESTRICT;
CREATE TABLE <表名>(
<列名> <数据类型>[ <列级完整性约束条件> ]
[,<列名> <数据类型>[ <列级完整性约束条件>] ]
………
[,<表级完整性约束条件> ]
);
如果完整性约束条件涉及到该表的多个属性列,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。
域
的概念用数据类型
来实现属性
时 需要指明其数据类型及长度
ALTER TABLE <表名>
[ ADD <新列名> <数据类型> [ 完整性约束 ] ]
[ DROP <完整性约束名> ]
[ ALTER COLUMN<列名> <数据类型> ];
[例8]向Student表增加“入学时间”列,其数据类型为日期型。
ALTER TABLE Student ADD S_entrance DATE;
[例9]将年龄的数据类型由字符型(假设原来的数据类型是字符型)改为整数。
ALTER TABLE Student ALTER COLUMN Sage INT;
ALTER TABLE Course ADD UNIQUE(Cname);
标准格式:
DROP TABLE <表名>[RESTRICT| CASCADE];
RESTRICT
:删除表是有限制的。
CASCADE
:删除该表没有限制。
[例11] 删除Student表
基本表定义被删除,数据被删除
表上建立的索引、视图、触发器等一般也将被删除
还是和上述删除模式情况一样,加了CASCADE和RESTRUCT删除不了
DROP TABLE Student CASCADE ;
[例12]若表上建有视图,选择RESTRICT时表不能删除
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS';
DROP TABLE Student RESTRICT;
456
--ERROR: cannot drop table Student because other objects depend on it
[例12]如果选择CASCADE时可以删除表,视图也自动被删除
DROP TABLE Student CASCADE;
--NOTICE: drop cascades to view IS_Student
SELECT * FROM IS_Student;
--ERROR: relation " IS_Student " does not exist
建立索引的目的:·加快查询速度·
CREATE INDEX
语句定义索引时,可以定义索引是唯一索引、非唯一索引或聚簇索引
语句格式
CREATE [UNIQUE] [CLUSTER] INDEX <索引名>
ON <表名>(<列名>[<次序>][,<列名>[<次序>] ]…);
[例13]
CREATE CLUSTERE INDEX Stusname ON Student(Sname);
聚簇索引
[例14]为学生-课程数据库中的Student,Course,SC三个表建 立索引。
CREATE UNIQUE INDEX Stusno ON Student(Sno);
CREATE UNIQUE INDEX Coucno ON Course(Cno);
CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC);
DROP INDEX <索引名> ON <表名>;
DROP INDEX <表名>.<索引名>;
[例15] 删除Student表的Stusname索引
DROP INDEX Stusno ON Student;
//等价
DROP INDEX Student.Stusno;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7DTPCznk-1648358301002)(https://gitee.com/fakerlove/picture_1/raw/master/20200329000307604.png)]
先从整体上了解一下SELECT的格式,关键字的位置。
SELECT [ALL|DISTINCT]
<目标列表达式> [别名] [ ,<目标列表达式> [别名]] …
FROM <表名或视图名> [别名] [ ,<表名或视图名> [别名]] …
[WHERE <条件表达式>]
[GROUP BY<列名1>
[HAVING <条件表达式>]]
[ORDER BY <列名2> [ASC|DESC]
4567
查询指定列
[例1] 查询全体学生的学号与姓名。
SELECT Sno,Sname
FROM Student;
[例2] 查询全体学生的姓名、学号、所在系。
SELECT Sname,Sno,Sdept
FROM Student;
12
[例3] 查询全体学生的详细记录。
SELECT Sno,Sname,Ssex,Sage,Sdept
FROM Student;
//两种方式
SELECT *FROM Student;
4
SELECT子句的<目标列表达式>可以为:
[例4] 查全体学生的姓名及其出生年份。这里假定目前年份是2004年。
SELECT Sname,2004-Sage
FROM Student;
[例5] 查询全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名,这里假定目前年份是2004年。
SELECT Sname,'Year of Birth: ', 2004-Sage, LOWER(Sdept)
FROM Student;
SELECT Sname NAME,'Year of Birth: ' BIRTH,
2000-Sage BIRTHDAY,
LOWER(Sdept) DEPARTMENT
FROM Student;
SELECT Sno FROM SC;
/*等价于:*/
SELECT ALL Sno FROM SC;
[例6] 查询选修了课程的学生学号。指定DISTINCT
关键词,去掉表中重复的行
SELECT DISTINCT Sno
FROM SC;
查询条件 | 谓词 |
---|---|
比较 | =,>,<,>=,<=,!=,<>,!>,!<;NOT+上述比较运算符 |
确定范围 | BETWEEN AND,NOT BETWEEN AND |
确定集合 | IN,NOT IN |
字符匹配 | LIKE,NOT LIKE |
空值 | IS NULL,IS NOT NULL |
多重条件(逻辑运算) | AND,OR,NOT |
[例7]查询计算机科学系全体学生的名单。
SELECT Sname
FROM Student
WHERE Sdept='CS';
SELECT Sname,Sage
FROM Student
WHERE Sage < 20;
SELECT DISTINCT Sno
FROM SC
WHERE Grade<60;
谓词:
BETWEEN … AND …
NOT BETWEEN … AND …
[例10] 查询年龄在20~23岁(包括20岁和23岁)之间的学生的
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage
BETWEEN 20 AND 23;
[例11] 查询年龄不在20~23岁之间的学生姓名、系别和年龄
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;
谓词:
IN <值表>,
NOT IN <值表>
[例12]查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。
SELECT Sname,Ssex
FROM Student
WHERE Sdept IN ( 'IS','MA','CS' );
[例13]查询既不是信息系、数学系,也不是计算机科学系的学生的姓名和性别。
SELECT Sname,Ssex
FROM Student
WHERE Sdept NOT IN ( 'IS','MA','CS' );
谓词:
[NOT] LIKE ‘<匹配串>’ [ESCAPE ‘ <换码字符>’]
匹配串为固定字符串
[例14] 查询学号为201215121的学生的详细情况。
SELECT *
FROM Student
WHERE Sno LIKE '201215121';
/*等价于:*/
SELECT *
FROM Student
WHERE Sno = '201215121';
匹配串为含通配符的字符串
[例15] 查询所有姓刘学生的姓名、学号和性别。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname LIKE '刘%';
SELECT Sname
FROM Student
WHERE Sname LIKE '欧阳_';
[例17] 查询名字中第2个字为"阳"字的学生的姓名和学号。
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '_阳%';
[例18] 查询所有不姓刘的学生姓名。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname NOT LIKE '刘%';
ESCAPE '\' 表示“ \” 为换码字符
[例19] 查询DB_Design课程的课程号和学分。
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design' ESCAPE '\';
[例20] 查询以"DB_"开头,且倒数第3个字符为 i的课程的详细情况。
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i_ _' ESCAPE '\';
谓词:
IS NULL
IS NOT NULL
“IS” 不能用 “=” 代替
[例21] 某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL;
[例22] 查所有有成绩的学生学号和课程号。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;
逻辑运算符:
可用来实现多种其他谓词
[NOT] IN
[NOT] BETWEEN … AND …
[例23] 查询计算机系年龄在20岁以下的学生姓名。
SELECT Sname
FROM Student
WHERE Sdept= 'CS' AND Sage<20;
改写[例12] 查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。
SELECT Sname,Ssex
FROM Student
WHERE Sdept IN ( 'IS','MA','CS' );
/*可改写为:*/
SELECT Sname,Ssex
FROM Student
WHERE Sdept= 'IS' OR Sdept= 'MA' OR Sdept= 'CS';
ORDER BY子句
可以按一个或多个属性列排序;
升序:ASC;
降序:DESC;
缺省值为升序;
当排序列含空值时
ASC
:排序列为空值的元组最后显示
DESC
:排序列为空值的元组最先显示
[例24] 查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。
SELECT Sno,Grade
FROM SC
WHERE Cno= '3'
ORDER BY Grade DESC;
4
[例25] 查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
SELECT *
FROM Student
ORDER BY Sdept,Sage DESC;
聚集函数:
COUNT([DISTINCT|ALL] *)
COUNT([DISTINCT|ALL] <列名>)
SUM([DISTINCT|ALL] <列名>)
AVG([DISTINCT|ALL] <列名>)
MAX([DISTINCT|ALL] <列名>)
MIN([DISTINCT|ALL] <列名>)
[例26] 查询学生总人数。
SELECT COUNT(*)
FROM Student;
SELECT COUNT(DISTINCT Sno)
FROM SC;
SELECT AVG(Grade)
FROM SC
WHERE Cno= '2';
[例29] 查询选修2号课程的学生最高分数。
SELECT MAX(Grade)
FROM SC
WHERE Cno= '2';
[例30]查询学生201215121选修课程的总学分数。
SELECT SUM(Ccredit)
FROM SC, Course
WHERE Sno='201215121' AND SC.Cno=Course.Cno;
GROUP BY
子句分组:
细化聚集函数的作用对象
HAVING
短语与WHERE
子句的区别:
基表或视图
,从中选择满足条件的元组
组
,从中选择满足条件的组
。[例31] 求各个课程号及相应的选课人数。
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
[例32] 查询选修了2门以上课程的学生学号。
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*) >2;
连接查询:同时涉及多个表的查询
连接条件或连接谓词:用来连接两个表的条件
一般格式:
[<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>
[<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>
连接字段:连接谓词中的列名称
常用于=连接
等值连接:连接运算符为=
[例33] 查询每个学生及其选修课程的情况
SELECT Student.*,SC.*
FROM Student,SC
WHERE Student.Sno = SC.Sno;
自然连接
[例34] 对[例33]用自然连接完成。
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student,SC
WHERE Student.Sno = SC.Sno;
[例35]查询每一门课的间接先修课(即先修课的先修课
)
SELECT FIRST.Cno,SECOND.Cpno
FROM Course FIRST,Course SECOND
WHERE FIRST.Cpno = SECOND.Cno;
SQL join 用于把来自两个或多个表的行结合起来。
标准格式:
SELECT column_name(s)
FROM table1//左表
<xxx JOIN> table2//右表
ON table1.column_name=table2.column_name;
分类:
INNER JOIN (JOIN)
LEFT JOIN (LEFT OUTER JOIN)
RIGHT JOIN (RIGHT OUTER JOIN)
FULL JOIN (FULL OUTER JOIN)
这里就以SC和Course两个表来检验这四类连接
SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC INNER JOIN Course ON (SC.Cno=Course.Cno);
/*INNER JOIN 与 JOIN结果相同*/
SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC JOIN Course ON (SC.Cno=Course.Cno);
LEFT JOIN
:关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC LEFT JOIN Course ON (SC.Cno=Course.Cno);
/*LEFT JOIN 与 LEFT OUTER JOIN结果相同*/
SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC LEFT OUTER JOIN Course ON (SC.Cno=Course.Cno);
SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC RIGHT JOIN Course ON (SC.Cno=Course.Cno);
/*RIGHT JOIN 与 RIGHT OUTER JOIN结果相同*/
SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC RIGHT OUTER JOIN Course ON (SC.Cno=Course.Cno);
FULL JOIN
:关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行。结合了 LEFT JOIN 和 RIGHT JOIN 的结果。SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC FULL JOIN Course ON (SC.Cno=Course.Cno);
/*FULL JOIN 与 FULL OUTER JOIN结果相同*/
SELECT Sno,SC.Cno,Grade,Course.Cno,Cname,Cpno,Ccredit
FROM SC FULL OUTER JOIN Course ON (SC.Cno=Course.Cno);
复合条件连接:WHERE子句中含多个连接条件
[例37]查询选修2号课程且成绩在88分以上的所有学生
SELECT Student.Sno, Sname
FROM Student,SC
WHERE Student.Sno = SC.Sno AND
/* 连接谓词*/
SC.Cno= '2' AND SC.Grade > 88;
/* 其他限定条件 */
SELECT Student.Sno,Sname,Cname,Grade
FROM Student,SC,Course /*多表连接*/
WHERE Student.Sno = SC.Sno
and SC.Cno = Course.Cno;
查询块
查询块嵌套
在另一个查询块
的WHERE
子句或HAVING
短语的条件中的查询称为嵌套查询
一个例子:
SELECT Sname/*外层查询/父查询*/
FROM Student
WHERE Sno IN
(SELECT Sno /*内层查询/子查询*/
FROM SC
WHERE Cno= '2');
限制
: ·不能使用ORDER BY子句·
子查询的查询条件不依赖于父查询
子查询的查询条件依赖于父查询
[例39] 查询与“刘晨”在同一个系学习的学生。此查询要求可以分步来完成
SELECT Sdept
FROM Student
WHERE Sname= '刘晨';
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept= 'CS';
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname= '刘晨');
[例40]查询选修了课程名为“信息系统”的学生学号和姓名
SELECT Sno,Sname /*③ 最后在Student关系中取出Sno和Sname*/
FROM Student
WHERE Sno IN
( SELECT Sno /*② 然后在SC关系中找出选修了3号课程的学生学号*/
FROM SC
WHERE Cno IN
( SELECT Cno /*① 首先在Course关系中找出 “信息系统”的课程号,为3号*/
FROM Course
WHERE Cname= '信息系统'
)
);
用连接查询实现[例40]
SELECT Student.Sno,Sname
FROM Student,SC,Course
WHERE Student.Sno = SC.Sno
AND SC.Cno = Course.Cno
AND Course.Cname='信息系统';
单个值
时,可以用>、<、=、>=、<= 、!=或< >等比较运算符
。例:假设一个学生只可能在一个系学习,并且必须属于一个系,则在[例39]可以用= 代替IN
:
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept =
(SELECT Sdept
FROM Student
WHERE Sname= '刘晨');
/*两种方式都可以*/
SELECT Sno,Sname,Sdept
FROM Student
WHERE
(SELECT Sdept
FROM Student
WHERE Sname= '刘晨')
= Sdept ;
SELECT Sno, Cno
FROM SC x
WHERE Grade >=(SELECT AVG(Grade) /*相关子查询*/
FROM SC y
WHERE y.Sno=x.Sno
);
[例41]可能的执行过程:
1.从外层查询中取出SC的一个元组x,将元组x的Sno值(201215121)传送给内层查询。
SELECT AVG(Grade)
FROM SC y
WHERE y.Sno='201215121';
2.执行内层查询,得到值88(近似值),用该值代替内层查询,得到外层查询:
SELECT Sno, Cno
FROM SC x
WHERE Grade >=88;
3.执行这个查询,得到
(200215121,1)
(200215121,3)
4.外层查询取出下一个元组重复做上述1至3步骤
,直到外层的SC元组全部处理完毕。结果为:
谓词语义:
ANY:任意一个值
ALL:所有值
需要配合使用比较运算符:
> ANY | 大于子查询结果中的某个值 |
> ALL | 大于子查询结果中的所有值 |
< ANY | 小于子查询结果中的某个值 |
< ALL | 小于子查询结果中的所有值 |
>= ANY | 大于等于子查询结果中的某个值 |
>= ALL | 大于等于子查询结果中的所有值 |
<= ANY | 小于等于子查询结果中的某个值 |
<= ALL | 小于等于子查询结果中的所有值 |
= ANY | 等于子查询结果中的某个值 |
=ALL | 等于子查询结果中的所有值(通常没有实际意义) |
!=(或<>)ANY | 不等于子查询结果中的某个值 |
!=(或<>)ALL | 不等于子查询结果中的任何一个值 |
[例42] 查询其他系中比计算机科学某一学生年龄小的学生姓名和年龄
SELECT Sname,Sage
FROM Student
WHERE Sage < ANY (SELECT Sage
FROM Student
WHERE Sdept= 'CS')
AND Sdept <> 'CS' ; /*父查询块中的条件 */
关系数据库管理系统(Relational Database Management System:RDBMS)
RDBMS执行此查询时,首先处理子查询,找出 CS系中所有学生的年龄,构成一个集合(20,19)
处理父查询,找所有不是CS系且年龄小于 20 或 19的学生
用聚集函数实现[例42]
SELECT Sname,Sage
FROM Student
WHERE Sage < (SELECT MAX(Sage)
FROM Student
WHERE Sdept= 'CS')
AND Sdept <> 'CS';
[例43] 查询其他系中比计算机科学系所有学生年龄都小的学生姓名及年龄。
SELECT Sname,Sage
FROM Student
WHERE Sage < ALL (SELECT Sage
FROM Student
WHERE Sdept= 'CS')
AND Sdept <> 'CS';
SELECT Sname,Sage
FROM Student
WHERE Sage < (SELECT MIN(Sage)
FROM Student
WHERE Sdept= 'CS')
AND Sdept <> 'CS';
ANY(或SOME),ALL谓词与聚集函数、IN谓词的等价转换关系
= | <>或!= | < | <= | > | >= | |
---|---|---|---|---|---|---|
ANY | IN | – | <=MAX |
>MIN |
>=MIN |
|
ALL | – | NOT IN | <=MIN |
>MAX |
>=MAX |
|
EXISTS谓词
NOT EXISTS谓词
[例44]查询所有选修了1号课程的学生姓名。
思路分析:
1.用嵌套查询
SELECT Sname
FROM Student
WHERE EXISTS(SELECT *
FROM SC
WHERE Sno=Student.Sno
AND Cno= '1');
2.用连接运算
SELECT Sname
FROM Student, SC
WHERE Student.Sno=SC.Sno
AND SC.Cno= '1';
[例45] 查询没有选修1号课程的学生姓名。
SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *
FROM SC
WHERE Sno=Student.Sno
AND Cno= '1');
不同形式的查询间的替换
SELECT Sno,Sname,Sdept
FROM Student S1
WHERE EXISTS(SELECT *
FROM Student S2
WHERE S2.Sdept = S1.Sdept
AND S2.Sname = '刘晨');
[例46] 查询选修了全部课程的学生姓名。
SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *
FROM Course
WHERE NOT EXISTS(SELECT *
FROM SC
WHERE Sno= Student.Sno
AND Cno= Course.Cno)
);
用EXISTS/NOT EXISTS实现逻辑蕴函(难点)
SELECT DISTINCT Sno
FROM SC SCX
WHERE NOT EXISTS(SELECT *
FROM SC SCY
WHERE SCY.Sno = '201215122'
AND NOT EXISTS(SELECT *
FROM SC SCZ
WHERE SCZ.Sno=SCX.Sno
AND SCZ.Cno=SCY.Cno
)
);
并操作UNION
交操作INTERSECT
差操作EXCEPT
参加集合操作的各查询结果
的列数必须相同
;对应项的数据类型也必须相同
[例48] 查询计算机科学系的学生及年龄不大于19岁的学生。
方法一:
SELECT *
FROM Student
WHERE Sdept= 'CS'
UNION SELECT *
FROM Student
WHERE Sage<=19;
UNION
:将多个查询结果合并
起来时,系统自动去掉重复元组
。UNION ALL
:将多个查询结果合并
起来时,保留重复元组
方法二:
SELECT DISTINCT *
FROM Student
WHERE Sdept= 'CS'
OR Sage<=19;
[例49] 查询选修了课程1或者
选修了课程2的学生。
SELECT Sno
FROM SC
WHERE Cno='1'
UNION
SELECT Sno
FROM SC
WHERE Cno= '2';
[例50] 查询计算机科学系的学生与年龄不大于19岁的学生的交集
SELECT *
FROM Student
WHERE Sdept='CS'
INTERSECT
SELECT *
FROM Student
WHERE Sage<=19;
[例50] 实际上就是查询计算机科学系中年龄不大于19岁的学生
SELECT *
FROM Student
WHERE Sdept= 'CS'
AND Sage<=19;
[例51] 查询选修课程1的学生集合与选修课程2的学生集合的交集
SELECT Sno
FROM SC
WHERE Cno='1'
INTERSECT
SELECT Sno
FROM SC
WHERE Cno='2';
[例51]实际上是查询既选修了课程1又
选修了课程2 的学生
SELECT Sno
FROM SC
WHERE Cno='1' AND Sno IN
(SELECT Sno
FROM SC
WHERE Cno='2');
[例52] 查询计算机科学系的学生与年龄不大于19岁的学生的差集
。
SELECT *
FROM Student
WHERE Sdept='CS'
EXCEPT
SELECT *
FROM Student
WHERE Sage <=19;
[例52]实际上是查询计算机科学系中年龄大于19岁的学生
SELECT *
FROM Student
WHERE Sdept= 'CS'
AND Sage>19;
两种插入数据方式
语句格式
INSERT
INTO <表名> [(<属性列1>[,<属性列2 >…)]
VALUES (<常量1> [,<常量2>] … )
功能:将新元组插入指定表中
INTO子句
VALUES子句
[例1] 将一个新学生元组(学号:200215128;姓名:陈冬;性别:男;所在系:IS;年龄:18岁)插入到Student表中。
INSERT
INTO Student (Sno,Sname,Ssex,Sdept,Sage)
VALUES ('200215128','陈冬','男','IS',18);
INSERT
INTO Student
VALUES ('200215126', '张成民', '男',18,'CS');
[例3] 插入一条选课记录( ‘200215128’,'1 ')。
INSERT
INTO SC(Sno,Cno)//RDBMS将在新插入记录的Grade列上自动地赋空值
VALUES ('200215128','1');
//等价
INSERT
INTO SC
VALUES ('200215128','1',NULL);
语句格式
INSERT
INTO <表名> [(<属性列1> [,<属性列2>… )]
子查询;
功能
将子查询结果插入指定表中
INTO子句(与插入元组类似)
子查询
[例4] 对每一个系,求学生的平均年龄,并把结果存入数据库。
第一步:建表
CREATE TABLE Dept_age(
Sdept CHAR(15), /* 系名*/
Avg_age SMALLINT /*学生平均年龄*/
);
第二步:插入数据
INSERT INTO Dept_age(Sdept,Avg_age)
SELECT Sdept,AVG(Sage)
FROM Student
GROUP BY Sdept;
RDBMS在执行插入语句时会检查所插元组是否破坏表上已定义的完整性规则
语句格式
UPDATE <表名>
SET <列名>=<表达式>[,<列名>=<表达式>]…
[WHERE <条件>];
功能
修改指定表中满足WHERE子句条件的元组
SET子句
WHERE子句
缺省表示要修改表中的所有元组
三种修改方式
[例5] 将学生201215121的年龄改为22岁
UPDATE Student
SET Sage=22
WHERE Sno='201215121';
[例6] 将所有学生的年龄增加1岁
UPDATE Student
SET Sage= Sage+1;
UPDATE SC
SET Grade=0
WHERE 'CS'=(
SELECT Sdept
FROM Student
WHERE Student.Sno = SC.Sno
);
RDBMS在执行修改语句时会检查修改操作是否破坏表上已定义的完整性规则
三种删除方式
DELETE
FROM Student
WHERE Sno= '200215128';
[例9] 删除所有的学生选课记录。
DELETE
FROM SC;//这个我就不截图了
[例10] 删除计算机科学系所有学生的选课记录。
DELETE
FROM SC
WHERE 'CS'=(
SELECT Sdept
FROM Student
WHERE Student.Sno=SC.Sno
);
视图的作用:
视图的特点
基于视图的操作
视图的UPDATE、DELETE、INSERT INTO(有受限),与基本表同步。
CREATE VIEW <视图名> [(<列名> [,<列名>]…)]
AS <子查询>
[WITH CHECK OPTION];
子查询不允许
含有ORDER BY
子句和DISTINCT
短语数据字典
,并不执行其中的SELECT语句。[例1] 建立信息系IS学生的视图。
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS';
[例2]建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系IS的学生 。
对IS_Student视图的更新操作:
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS'
WITH CHECK OPTION;
[例3] 建立信息系选修了1号课程的学生视图。
CREATE VIEW IS_S1(Sno,Sname,Grade)
AS
SELECT Student.Sno,Sname,Grade
FROM Student,SC
WHERE Sdept= 'IS'
AND Student.Sno=SC.Sno
AND SC.Cno= '1';
[例4] 建立信息系选修了1号课程且成绩在90分以上的学生的视图。
CREATE VIEW IS_S2
AS
SELECT Sno,Sname,Grade
FROM IS_S1
WHERE Grade>=90;
带表达式的视图
[例5] 定义一个反映学生出生年份的视图。
CREATE VIEW BT_S(Sno,Sname,Sbirth)
AS
SELECT Sno,Sname,2000-Sage
FROM Student;
分组视图
[例6] 将学生的学号及他的平均成绩定义为一个视图
CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
不指定属性列
[例7]将Student表中所有女生记录定义为一个视图
CREATE VIEW F_Student(F_Sno,name,sex,age,dept)
AS
SELECT *
FROM Student
WHERE Ssex='女';
缺点:
语句的格式:
DROP VIEW <视图名>;
数据字典
中删除指定的视图定义CASCADE级联
删除语句,把该视图和由它导出的所有视图一起删除[例8] 删除视图IS_S1
DROP VIEW IS_S1;
用户角度:查询视图与查询基本表相同
RDBMS实现视图查询的方法
修正
后的查询关系数据库管理系统执行对视图的查询时,首先进行有效性检查
,检查查询中涉及的表、视图等是否存在。如果存在,则从数据字典
中取出视图的定义,把定义中的子查询
和用户的查询
结合起来,转换成等价的对基本表的查询
,然后再执行修正了的查询
。这一转换过程称为视图消解
(view resolution)。
[例9] 在信息系学生的视图中找出年龄小于等于20岁的学生。
SELECT Sno,Sage
FROM IS_Student
WHERE Sage<=20;
IS_Student视图的定义 (参见视图定义例1)
视图消解转换后的查询语句为:
SELECT Sno,Sage
FROM Student
WHERE Sdept= 'IS' AND Sage<=20;
[例10] 查询选修了1号课程的信息系学生
SELECT IS_Student.Sno,Sname
FROM IS_Student,SC
WHERE IS_Student.Sno =SC.Sno AND SC.Cno= '1';
视图消解法的局限
[例11]在S_G视图中查询平均成绩在90分以上的学生学号和平均成绩
SELECT *
FROM S_G
WHERE Gavg>=90;
S_G视图的子查询定义:
CREATE VIEW S_G (Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
错误:
SELECT Sno,AVG(Grade)
FROM SC
WHERE AVG(Grade)>=90
GROUP BY Sno;
正确:
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
[例12] 将信息系学生视图IS_Student中学号201215125的学生姓名改为“刘辰”。
UPDATE IS_Student
SET Sname= '刘辰'
WHERE Sno= '201215125';
转换后的语句://基本表和视图表同步更新
UPDATE Student
SET Sname= '刘辰'
WHERE Sno= '201215125'
AND Sdept= 'IS';
[例13] 向信息系学生视图IS_Student中插入一个新的学生记录:200215111,赵新,20岁
视图IS_Student的定义
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS';
//如果加了WITH CHECK OPTION,则视图不能进行插入数据操作
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS'
WITH CHECK OPTION;
//插入数据
INSERT
INTO IS_Student
VALUES('200215111','赵新',20);
//插入后基本表Student字段Sdept为空,视图表IS_Student无数据
转换为对基本表的更新:
INSERT
INTO Student(Sno,Sname,Sage,Sdept)
VALUES('200215129','赵新2',20,'IS');
4567891011121314151617181920212223
[例14]删除信息系学生视图IS_Student中学号为200215129的记录
DELETE
FROM IS_Student
WHERE Sno= '200215129';
转换为对基本表的更新:
DELETE
FROM Student
WHERE Sno= '200215129' AND Sdept= 'IS';
4567
更新视图的限制:
一些视图是不可更新的,因为对这些视图的更新不能唯一地有意义地转换成对相应基本表的更新UPDATE S_G
SET Gavg=90
WHERE Sno= '200215121';
这个对视图的更新无法转换成对基本表SC的更新
not null,unique,码属性
执行视图查询时,先进行有效性检查。如果视图、表都存在,就取出视图定义,把定义中的子查询和用户查询结合起来,转换成等价的对基本表的查询。这一转换过程被称为视图分解。
在一个项目的实际开发过程中牵涉到复杂业务的时候,我们不可避免的需要使用中间表来进行数据连接,有的同学就说了,我可以采用Hibernate进行主外键进行关联啊?多对多,多对一,一对一,等,采用主外键关联在数据的操作过程中具有很强的耦合性,尤其对于需要经常删改数据表而言,我们是不建议采用主外键关联这种模式,那么,如果我们采用中间表的话,当数据过大在性能上又面临严峻考验,sql视图的出现,在解决中间表的业务逻辑上是不错的选择。ok,首先我们了解什么是视图?
1、视图是表?没错,但是是一张虚拟表,视图的字段是由我们自定义的,视图只供查询,数据不可更改,查询数据来源于我们建立的实体表。
2、使用视图的优势?视图可以将多个复杂关联表,提取出我们需要的信息,优化查询速度。
如何创建视图?
我们先建立三张表;如下:
这个是典型的一对多和一对一的关系,那么,假如每张表的数据都在一万条数据以上,现在查询在潢高上学的学生姓名?
首先,我们分析一下,在潢高上学?首先是一个高中,那么我们会有一条Sql where school=‘潢高’,
查询出一个List,得到gradeids,然后再到grade中根据gradeids查询这么多grades对应的studentids,在使用这些studentsid查询出students循环最后得到name?
是不是很累赘?查询是不是很影响性能?
观察得知,这三张表每两张表之间都是通过id进行关联的,如果我们通过id将三张表组成一张表,是不是很方便?
我们来关联学校表和年级表:这个年级ID我们不要,ok?
select s.id as schoolId,s.school as schoolName,s.gradeid as gradeid,g.grade as gradeName,g.studentid as studentid from school s,grade g where s.gradeid=g.id;
那么我们再关联上学生表,学生表的id等于年级表的studentid ok?
SELECT s.id as schoolId,s.school as schoolName,s.gradeid as gradeid,g.grade as gradeName,g.studentid as studentid ,t.`name` as studentName,t.age as studentAge
from school s,grade g,student t where s.gradeid=g.id and g.studentid=t.id;
ok,到了这里?我们再看运行结果?
那么我们想查询在潢高上学的学生姓名,where schoolName=‘潢高’,获取的list循环得到Object,通过Object.getStudentName,就可以了?
所以需要将查询到的结果,建立为一张虚拟表,这样才能操作,通过这个create view 视图名 as 命令建立:
意思就是将查询结果创建为名称为table_sgt的一张虚拟表:
create view table_sgt as(select s.id as schoolId,s.school as schoolName,s.gradeid as gradeid,g.grade as gradeName,g.studentid as studentid ,t.`name` as studentName,t.age as studentAge from school s,grade g,student t where s.gradeid=g.id and g.studentid=t.id);
我们在使用视图的时候,需要把它看做为一张表,建立一张实体表需要做的步骤,视图也都需要(例如,实例化,配置映射文件,对象的属性get,set方法)
注意视图所查询出来的数据只能进行查看,不能增删改!
视图是不实际存储数据的虚表,因此对视图的更新,最终要转换为对基本表的更新。因为有些视图的更新不能惟一有意义地转换成对相应基本表的更新,所以,并不是所有的视图都是可更新的.
基本表的行列子集视图一般是可更新的。若视图的属性来自集合函数、表达式,则该视图肯定是不可以更新的。
ADD | ALL | ALTER |
---|---|---|
ANALYZE | AND | AS |
ASC | ASENSITIVE | BEFORE |
BETWEEN | BIGINT | BINARY |
BLOB | BOTH | BY |
CALL | CASCADE | CASE |
CHANGE | CHAR | CHARACTER |
CHECK | COLLATE | COLUMN |
CONDITION | CONNECTION | CONSTRAINT |
CONTINUE | CONVERT | CREATE |
CROSS | CURRENT_DATE | CURRENT_TIME |
CURRENT_TIMESTAMP | CURRENT_USER | CURSOR |
DATABASE | DATABASES | DAY_HOUR |
DAY_MICROSECOND | DAY_MINUTE | DAY_SECOND |
DEC | DECIMAL | DECLARE |
DEFAULT | DELAYED | DELETE |
DESC | DESCRIBE | DETERMINISTIC |
DISTINCT | DISTINCTROW | DIV |
DOUBLE | DROP | DUAL |
EACH | ELSE | ELSEIF |
ENCLOSED | ESCAPED | EXISTS |
EXIT | EXPLAIN | FALSE |
FETCH | FLOAT | FLOAT4 |
FLOAT8 | FOR | FORCE |
FOREIGN | FROM | FULLTEXT |
GOTO | GRANT | GROUP |
HAVING | HIGH_PRIORITY | HOUR_MICROSECOND |
HOUR_MINUTE | HOUR_SECOND | IF |
IGNORE | IN | INDEX |
INFILE | INNER | INOUT |
INSENSITIVE | INSERT | INT |
INT1 | INT2 | INT3 |
INT4 | INT8 | INTEGER |
INTERVAL | INTO | IS |
ITERATE | JOIN | KEY |
KEYS | KILL | LABEL |
LEADING | LEAVE | LEFT |
LIKE | LIMIT | LINEAR |
LINES | LOAD | LOCALTIME |
LOCALTIMESTAMP | LOCK | LONG |
LONGBLOB | LONGTEXT | LOOP |
LOW_PRIORITY | MATCH | MEDIUMBLOB |
MEDIUMINT | MEDIUMTEXT | MIDDLEINT |
MINUTE_MICROSECOND | MINUTE_SECOND | MOD |
MODIFIES | NATURAL | NOT |
NO_WRITE_TO_BINLOG | NULL | NUMERIC |
ON | OPTIMIZE | OPTION |
OPTIONALLY | OR | ORDER |
OUT | OUTER | OUTFILE |
PRECISION | PRIMARY | PROCEDURE |
PURGE | RAID0 | RANGE |
READ | READS | REAL |
REFERENCES | REGEXP | RELEASE |
RENAME | REPEAT | REPLACE |
REQUIRE | RESTRICT | RETURN |
REVOKE | RIGHT | RLIKE |
SCHEMA | SCHEMAS | SECOND_MICROSECOND |
SELECT | SENSITIVE | SEPARATOR |
SET | SHOW | SMALLINT |
SPATIAL | SPECIFIC | SQL |
SQLEXCEPTION | SQLSTATE | SQLWARNING |
SQL_BIG_RESULT | SQL_CALC_FOUND_ROWS | SQL_SMALL_RESULT |
SSL | STARTING | STRAIGHT_JOIN |
TABLE | TERMINATED | THEN |
TINYBLOB | TINYINT | TINYTEXT |
TO | TRAILING | TRIGGER |
TRUE | UNDO | UNION |
UNIQUE | UNLOCK | UNSIGNED |
UPDATE | USAGE | USE |
USING | UTC_DATE | UTC_TIME |
UTC_TIMESTAMP | VALUES | VARBINARY |
VARCHAR | VARCHARACTER | VARYING |
WHEN | WHERE | WHILE |
WITH | WRITE | X509 |
XOR | YEAR_MONTH | ZEROFILL |
保护数据库以防止不合法使用所造成的的数据泄露、更改或破坏
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ll24oL8u-1648358301058)(https://gitee.com/fakerlove/picture_1/raw/master/20200424232640388.png)]
问题的提出:
数据库系统中的数据共享不能是无条件的共享
非法使用数据库的情况:
B2以上的系统:
数据库安全性控制的常用方法:
是系统提供的最外层安全保护措施
常用的用户身份鉴别方法有以下几种:
静态口令一般由用户自己设定,鉴别时只要按要求输入正确的口令,系统将允许用户使用数据库管理系统。
常用的方式如短信密码和动态令牌方式,每次鉴别时要求用户使用通过短信或令牌等途径获取的新口令登录数据库管理系统。
指纹、虹膜和掌纹等
。智能卡由用户随身携带,登录数据库管理系统时用户将智能卡插入专用的读卡器进行身份验证。
个人身份识别码(PIN)和智能卡
相结合的方式。这样,即使PIN或智能卡中有一种被窃取,用户身份仍不会被冒充。主要通过数据库系统的存取控制机制实现。
定义用户权限
,并将用户权限登记到数据字典中;合法权限检查
,每当用户发出存取数据库的操作请求后(请求一般应包括操作类型、操作对象和操作用户等信息),数据库管理系统查找数据字典,根据安全规则进行合法权限检查
,若用户的操作请求超出了定义的权限,系统将拒绝执行此操作。定义用户权限
和合法权限检查机制
一起组成了数据库管理系统的存取控制子系统
。
C2级
的数据库管理系统支持自主存取控制
( Discretionary Access Control, DAC),B1级
的数据库管理系统支持强制存取控制
( Mandatory Access Control, MAC)。这两类方法的简单定义是:
自主存取控制
方法中,用户对于不同的数据库对象有不同的存取权限,不同的用户对同一对象也有不同的权限,而且用户还可将其拥有的存取权限转授给其他用户。因此自主存取控制非常灵活。强制存取控制
方法中,每一个 数据库对象被标以一定的密级,每一个用户也被授予某一个级别的许可证。对于任意一个对象, 只有具有合法许可证的用户才可以存取。强制存取控制因此相对比较严格。GRANT
语句和 REVOKE
语句实现数据对象
操作类型
定义存取权限称为授权
GRANT语句的一般格式:
GRANT <权限>[,<权限>]...
[ON <对象类型> <对象名>]
TO <用户>[,<用户>]...
[WITH GRANT OPTION];
语义:将对指定操作对象的指定操作权限授予指定的用户
发出GRANT:
按受权限的用户:
WITH GRANT OPTION子句:
不允许循环授权:
[例1] 把查询Student表权限授给用户U1
GRANT SELECT
ON TABLE Student
TO U1;
举个例子而已,不同数据库请参考相关文档,先打基础。有个印象,知道有这么个东西,其实很多数据库管理系统已经将这些封装好了,简洁漂亮的UI,灵活的操作,基本不会用到语句来写。话不多说,直接上图:
[例2] 把对Student表和Course表的全部权限授予用户U2和U3
GRANT ALL PRIVILIGES
ON TABLE Student, Course
TO U2, U3;
[例3] 把对表SC的查询权限授予所有用户
GRANT SELECT
ON TABLE SC
TO PUBLIC;
[例4] 把查询Student表和修改学生学号的权限授给用户U4
对属性列的授权时必须明确指出相应属性列名
GRANT UPDATE(Sno), SELECT
ON TABLE Student
TO U4;
4
[例5] 把对表SC的INSERT权限授予U5用户,并允许他再将此权限授予其他用户
GRANT INSERT
ON TABLE SC
TO U5
WITH GRANT OPTION;
4
执行例5后,U5不仅拥有了对表SC的INSERT权限,
还可以传播此权限:
[例6]
GRANT INSERT ON TABLE SC TO U6
WITH GRANT OPTION;
12
同样,U6还可以将此权限授予U7:
[例7]
GRANT INSERT ON TABLE SC TO U7;
但U7不能再传播此权限,因为没有写这条语句WITH GRANT OPTION
。
授予的权限可以由DBA或其他授权者用REVOKE语句收回
REVOKE语句的一般格式为:
REVOKE <权限>[,<权限>]...
[ON <对象类型> <对象名>]
FROM <用户>[,<用户>]...;
[例8] 把用户U4修改学生学号的权限收回
REVOKE UPDATE(Sno)
ON TABLE Student
FROM U4;
[例9] 收回所有用户对表SC的查询权限
REVOKE SELECT
ON TABLE SC
FROM PUBLIC;
[例10] 把用户U5对SC表的INSERT权限收回
REVOKE INSERT
ON TABLE SC
FROM U5 CASCADE ;
将用户U5的INSERT权限收回的时候必须级联(CASCADE)收回 系统只收回直接或间接从U5处获得的权限
DBA在创建用户时实现
CREATE USER语句格式
CREATE USER <username>
[WITH][DBA | RESOURCE | CONNECT]
数据库角色:被命名的一组与数据库操作相关的权限
结合我刚刚上面截得黑色背景图片了解
CREATE ROLE <角色名>
GRANT <权限>[,<权限>]…
ON <对象类型>对象名
TO <角色>[,<角色>]…
GRANT <角色1>[,<角色2>]…
TO <角色3>[,<用户1>]…
[WITH ADMIN OPTION]
REVOKE <权限>[,<权限>]…
ON <对象类型> <对象名>
FROM <角色>[,<角色>]…
[例11] 通过角色来实现将一组权限授予一个用户。
步骤如下:
CREATE ROLE R1;
GRANT SELECT,UPDATE,INSERT
ON TABLE Student
TO R1;
GRANT R1
TO 王平,张明,赵玲;
12
REVOKE R1
FROM 王平;
12
[例12] 角色的权限修改
GRANT DELETE
ON TABLE Student
TO R1
[例13] 角色权限的收回
REVOKE SELECT
ON TABLE Student
FROM R1;
自主存取控制缺点:
强制存取控制(MAC):
保证更高程度的安全性
用户能不能直接感知或进行控制,因为对数据进行了加密
适用于对数据有严格而固定密级分类的部门
*军事部门
*政府部门
在强制存取控制中,数据库管理系统所管理的全部实体被分为主体和客体两大类。
主体
是系统中的活动实体客体
是系统中的被动实体,是受主体操纵的对于主体和客体,数据库管理系统为它们每个实例(值)指派一个敏感度标记(label)。
敏感度标记(Label)分为若干个级别:
主体的敏感度标记称为许可证级别
(Clearance Level)客体的敏感度标记称为密级
(Classification Level)强制存取控制规则:
大于或等于客体
的密级时,该主体才能读取
相应的客体等于
客体的密级时,该主体才能写
相应的客体主体的许可证级别 <=客体的密级→ 主体能写客体
规则的共同点:
禁止
了拥有高许可证级别的主体更新
低密级的数据对象把要保密的数据对无权存取这些数据的用户隐藏起来,对数据提供一定程度的安全保护
[例14]建立计算机系学生的视图,把对该视图的SELECT权限授于王平,把该视图上的所有操作权限授于张明
先建立计算机系学生的视图CS_Student
CREATE VIEW CS_Student AS
SELECT *
FROM Student
WHERE Sdept='CS';
在视图上进一步定义存取权限:
GRANT SELECT
ON CS_Student
TO 王平;
GRANT ALL PRIVILIGES
ON CS_Student
TO 张明;
什么是审计:
审计日志(Audit Log)
;审计分为:
用户级审计
系统级审计
AUDIT语句:设置审计功能
NOAUDIT语句:取消审计功能
[例15]对修改SC表结构或修改SC表数据的操作进行审计
AUDIT ALTER,UPDATE
ON SC;
[例16]取消对SC表的一切审计
NOAUDIT ALTER,UPDATE
ON SC;
存储
和传输
中失密的有效手段存储加密
和传输加密
透明和非透明
两种存储加密方式。透明
存储加密是内核级加密保护
方式,对用户完全透明
非透明
存储加密则是通过多个加密函数
实现的。透明存储加密
是数据在写到磁盘时对数据进行加密,授权用户读取数据时再对其进行解密。由于数据加密对用户透明,数据库的应用程序不需要做任何修改,只需在创建表语句中说明需加密的字段即可。当对加密数据进行增、删、改、查询操作时,数据库管理系统将自动对数据进行加、解密工作。基于数据库内核的数据存储加密、解密方法性能较好,安全完备性较高。链路加密和端到端加密
。统计数据库
统计数据库中特殊的安全性问题:
统计数据库安全性规则:
数据库安全机制的设计目标:
试图破坏安全的人所花费的代价 >> 得到的利益
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcfL9P3n-1648358301063)(https://gitee.com/fakerlove/picture_1/raw/master/2020040719260039.png)]
数据库完整性
指的是数据的正确性
和相容性
。正确性
是指数据是符合现实世界语义、反映当前实际状况的;比如说人类的性别,只能是男和女。相容性
是指数据库同一对象在不同关系表中的数据是符合逻辑的。比如说年龄一般都在1-100岁,当然也有超过一百岁的,反正没有两百岁,三百岁成仙的人类。1.提供定义完整性约束条件的机制
完整性规则
,是数据库中数据必须满足的语义条件规则2.提供完整性检查的方法
完整性检查
3.违约处理
关系模型的实体完整性
单属性构成的码有两种说明方法
对多个属性构成的码只有一种说明方法
举几个例子
将Student表中的Sno属性定义为码
(1)在列级定义主码
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY,
Sname CHAR(20) NOT NULL,
Ssex CHAR(2) ,
Sage SMALLINT,
Sdept CHAR(20));
(2)在表级定义主码
CREATE TABLE Student
(Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2) ,
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno)
);
将SC表中的Sno,Cno属性组定义为码
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno,Cno) /*只能在表级定义主码*/
);
插入或对主码列进行更新操作时,RDBMS按照实体完整性规则自动进行检查。包括:
自动建立一个索引
,如图5.2的B+树索引,通过索引查找基本表中是否已经存在新的主码值将大大提高效率。关系模型的参照完整性定义
FOREIGN KEY
短语定义哪些列为外码REFERENCES
短语指明这些外码参照哪些表的主码举个例子
例如,关系SC中一个元组表示一个学生选修的某门课程的成绩,
(Sno,Cno)是主码。
Sno,Cno分别参照引用Student表的主码和Course表的主码
定义SC中的参照完整性
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno, Cno), /*在表级定义实体完整性*/
FOREIGN KEY (Sno) REFERENCES Student(Sno),
/*在表级定义参照完整性*/
FOREIGN KEY (Cno) REFERENCES Course(Cno)
/*在表级定义参照完整性*/
);
参照完整性违约处理
外码列是否允许空值
[例4] 显式说明参照完整性的违约处理示例
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY(Sno,Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno)
ON DELETE CASCADE /*级联删除SC表中相应的元组*/
ON UPDATE CASCADE, /*级联更新SC表中相应的元组*/
FOREIGN KEY (Cno) REFERENCES Course(Cno)
ON DELETE NO ACTION
/*当删除course 表中的元组造成了与SC表不一致时拒绝删除*/
ON UPDATE CASCADE
/*当更新course表中的cno时,级联更新SC表中相应的元组*/
);
某一具体应用的数据
必须满足的语义要求CREATE TABLE时定义
1.不允许取空值
[例5] 在定义SC表时,说明Sno、Cno、Grade属性不允许取空值。
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT NOT NULL,
PRIMARY KEY (Sno, Cno),
/* 如果在表级定义实体完整性,隐含了Sno,Cno不允许取空值,
则在列级不允许取空值的定义就不必写了 */
);
2.列值唯一
[例6]建立部门表DEPT,要求部门名称Dname列取值唯一,
部门编号Deptno列为主码
CREATE TABLE DEPT
(Deptno NUMERIC(2),
Dname CHAR(9) UNIQUE,/*要求Dname列值唯一*/
Location CHAR(10),
PRIMARY KEY (Deptno)
);
3. 用CHECK短语指定列值应该满足的条件
[例7]Student表的Ssex只允许取“男”或“女”。
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY,
Sname CHAR(8) NOT NULL,
Ssex CHAR(2) CHECK (Ssex IN (‘男’,‘女’) ) ,
/*性别属性Ssex只允许取'男'或'女' */
Sage SMALLINT,
Sdept CHAR(20)
);
CHECK
短语定义元组上的约束条件,即元组级的限制
[例9] 当学生的性别是男时,其名字不能以Ms.打头。
CREATE TABLE Student
(Sno CHAR(9),
Sname CHAR(8) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno),
CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%')
/*定义了元组中Sname和 Ssex两个属性值之间的约束条件*/
);
性别是女性的元组都能通过该项检查,因为Ssex=‘女’成立;
当性别是男性时,要通过检查则名字一定不能以Ms.打头
详细的约束
CONSTRAINT <完整性约束条件名>
[PRIMARY KEY短语
|FOREIGN KEY短语
|CHECK短语]
举个例子:
[例10] 建立学生登记表Student,要求学号在90000~99999之间,
姓名不能取空值,年龄小于30,性别只能是“男”或“女”。
CREATE TABLE Student
(Sno NUMERIC(6)
CONSTRAINT C1 CHECK (Sno BETWEEN 90000 AND 99999),
Sname CHAR(20)
CONSTRAINT C2 check( NOT NULL),
Sage NUMERIC(3)
CONSTRAINT C3 CHECK (Sage < 30),
Ssex CHAR(2)
CONSTRAINT C4 CHECK (Ssex IN ( '男','女')),
CONSTRAINT StudentKey PRIMARY KEY(Sno)
);
在Student表上建立了5个约束条件,包括主码约束(命名为StudentKey)
以及C1、C2、C3、C4四个列级约束。
修改表中的完整性限制
[例13] 修改表Student中的约束条件,要求学号改为在900000~999999之间,
年龄由小于30改为小于40
可以先删除原来的约束条件,再增加新的约束条件
ALTER TABLE Student
DROP CONSTRAINT C1;
ALTER TABLE Student
ADD CONSTRAINT C1 CHECK (Sno BETWEEN 900000 AND 999999);
ALTER TABLE Student
DROP CONSTRAINT C3;
ALTER TABLE Student
ADD CONSTRAINT C3 CHECK (Sage < 40);
关于域的定义有些数据库可能不同,或者定义失败,得观看相关的手册深入学习,但是SQL中是有定义DOMAIN,初学先了解一下叭。
SQL支持域的概念,并可以用CREATE DOMAIN
语句建立一个域以及该域应该满足的完整性约束条件。
[例14]建立一个性别域,并声明性别域的取值范围
CREATE DOMAIN GenderDomain CHAR(2)
CHECK (VALUE IN ('男','女') );
这样[例10]中对Ssex的说明可以改写为Ssex GenderDomain
[例15]建立一个性别域GenderDomain,并对其中的限制命名
CREATE DOMAIN GenderDomain CHAR(2)
CONSTRAINT GD CHECK ( VALUE IN ('男','女') );
[例16]删除域GenderDomain的限制条件GD。
ALTER DOMAIN GenderDomain
DROP CONSTRAINT GD;
[例17]在域GenderDomain上增加限制条件GDD。
ALTER DOMAIN GenderDomain
ADD CONSTRAINT GDD CHECK (VALUE IN ( '1','0') );
通过[例16]和[例17],就把性别的取值范围由('男','女')改为 ( '1','0')
123456789101112131415161718
关于断言还是和域一样,不同的数据库可能实现方式不同,初学先了解,后期再深入
CREATE ASSERTION
语句,通过声明性断言(declarative assertions)来指定更具一般性的约束。标准语句格式:
CREATE ASSERTION <断言名> <CHECK子句>
[例5.18]限制数据库课程最多 60名学生选修。
CREATE ASSERTION ASSE_SC_DB_ NUM
CHECK(60>=(SELECT count(*)/*此断言的谓词涉及聚集操作count的SQL语句*/
FROM Course,SC
WHERE SC.Cno=Course.Cno AND Course.Cname=数据库)
);
每当学生选修课程时,将在SC表中插入一条元组(Sno, Cno, NULL),
ASSE_SC_DB_NUM断言被触发检查。如果选修数据库课程的人数已经超过60人,
CHECK子句返回值为“假”,对SC表的插入操作被拒绝。
[例5.19]限制每一 门课程最多60名学生选修。
CREATE ASSERTION ASSE_SC_CNUMI
CHECK( 60>=ALL( SELECT count (*)/*此断言的谓词,涉及聚集操作count */
FROM SC /*和分组函数group by的SQL语句*/
GROUP by cno );
[例5.20 限制每个学期每一门课程最多60名学生选修]
首先修改SC表的模式,增加一个“学期(TERM)”的属性。
ALTER TABLE SC ADD TERM DATE;
/*先修改SC表,增加TERM属性,它的类型是DATE*/
然后定义断言:
CREATE ASSERTION ASSE_SC_CNUM2
CHECK (60>=ALL ( select count (*) from SC group by Cno,TERM ));
DROP ASSERTION <断言名>;
事件驱动
的特殊过程CREATE TRIGGER语法格式:
CREATE TRIGGER <触发器名>
{BEFORE | AFTER} <触发事件> ON <表名>
FOR EACH {ROW | STATEMENT}
[WHEN <触发条件>]
<触发动作体>
定义触发器的语法说明:
UPDATE TEACHER SET Deptno=5;
语句
级触发器,那么执行完该语句后,触发动作只发生一次行级
触发器,触发动作将执行1000次[例18] 定义一个BEFORE行级触发器,
为教师表Teacher定义完整性规则“教授的工资不得低于4000元,
如果低于4000元,自动改为4000元”。
CREATE TRIGGER Insert_Or_Update_Sal
BEFORE INSERT OR UPDATE ON Teacher
/*触发事件是插入或更新操作*/
FOR EACH ROW /*行级触发器*/
AS BEGIN /*定义触发动作体,是PL/SQL过程块*/
IF (new.Job='教授') AND (new.Sal < 4000) THEN
new.Sal :=4000;
END IF;
END;
[例19]定义AFTER行级触发器,当教师表Teacher的工资发生变化后
就自动在工资变化表Sal_log中增加一条相应记录
首先建立工资变化表Sal_log
CREATE TABLE Sal_log
(Eno NUMERIC(4) references teacher(eno),
Sal NUMERIC(7,2),
Username char(10),
Date TIMESTAMP
);
[例19](续)
CREATE TRIGGER Insert_Sal
AFTER INSERT ON Teacher /*触发事件是INSERT*/
FOR EACH ROW
AS BEGIN
INSERT INTO Sal_log VALUES(
new.Eno,new.Sal,CURRENT_USER,CURRENT_TIMESTAMP);
END;
[例19](续)
CREATE TRIGGER Update_Sal
AFTER UPDATE ON Teacher /*触发事件是UPDATE */
FOR EACH ROW
AS BEGIN
IF (new.Sal <> old.Sal) THEN INSERT INTO Sal_log VALUES(
new.Eno,new.Sal,CURRENT_USER,CURRENT_TIMESTAMP);
END IF;
END;
这个可以在Oracle数据库里运行,但是因为我用的是SQL Sever数据库,所以运行不了,不同的数据库,触发器的实现略有不同,详情请查看相关数据库手册。
触发事件激活
的,并由数据库服务器自动执行多个触发器
[例20]执行修改某个教师工资的SQL语句,激活上述定义的触发器。
UPDATE Teacher SET Sal=800 WHERE Ename='王五';
执行顺序是:
执行触发器Insert_Or_Update_Sal
执行SQL语句“UPDATE Teacher SET Sal=800 WHERE Ename='王五';”
执行触发器Insert_Sal;
执行触发器Update_Sal
删除触发器的SQL语法:
DROP TRIGGER <触发器名> ON <表名>;
触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。
[例21] 删除教师表Teacher上的触发器Insert_Sal
DROP TRIGGER Insert_Sal ON Teacher;
数据完整性是为了防止数据库中存在不符合语义的概念,防止错误信息的输入和输出,即所谓垃圾进垃圾出所造成的无效操作和错误结果
数据的安全性是保护句酷防止恶意的破坏和非法的存取
感性认识:
数据库规范化理论
研究解决的问题,说白了就是告诉你如何才能设计出合适的库和表下面我们回顾几个概念和问题,以便更好地学习后面的关系数据库规范化理论
关系模式:即二维表的逻辑结构
关系型数据库这一系列的行和列被称为表,一组表组成了数据库
。关系模式由五部分组成,即它是一个五元组:
R(U, D, DOM, F)
R: 关系名,即表名
U:组成该关系的属性名集合
D: 属性组U中属性所来自的域。数据的取值范围和类型
DOM: 属性向域的映象集合
F:属性组U上的一组数据依赖。
关系数据库规范化理论研究的就是R、F、U,之间的关系。
因为D和DOM对研究表的设计关系不大,所以在学习关系数据库规范化理论时可以将五元组简化成三元组
三元组:
R(U, F)
当且仅当U上的一个关系r
满足F
时,r
称为关系模式 R(U, F)的一个关系
这里我们对F
中的数据依赖
进行简单解释,后面会详细叙述函数依赖
和多值依赖
。
数据依赖
是一个关系内部属性与属性之间的一种约束关系。
这种约束关系是通过属性间值的相等与否体现出来的数据间相关联系
。
它是现实世界属性间相互联系的抽象,是数据内在的性质,是语义的体现。
数据依赖分类:
函数依赖极为普遍地存在于现实生活中。比如描述一个学生的关系,可以有学号(Sno)、姓名(Sname)、 系名(Sdept) 等几个属性。由于一个学号只对应一个学生,一个学生只在一一个系学习。因而当“学号”值确定之后,学生的姓名及所在系的值也就被唯一地确定了。
属性间的这种依赖关系类似于数学中的函数y=f(x),自变量x确定之后,相应的函数值y也就唯一地确定 了。
因为关系数据库规范化理论
主要研究的是三元组R(U,F)
,U我们都好理解,最重要的是F,这里我们简单的了解一下F对关系模式,即表的逻辑结构的影响,让我们理性的认识为什么学习关系数据库规范化理论
举个例子:
[例1]建立一个描述学校教务的数据库,数据库涉及的对象有:
学生的学号(Sno)、所在系(Sdept)、系主任姓名(Mname)、课程名(Cname)、成绩(Grade)
这里我们用单一的关系模式Student来表示这些对象:
Student
该关系的属性集合:
U ={ Sno, Sdept, Mname, Cname, Grade }
这里说明一下现实世界的事实语义,关于这些对象之间的联系:
①一个系有若干学生,但一个学生只属于一个系。
②一个系只有一名(正职)负责人。
③一个学生可以选修多门课程,每门课程有若干学生选修。
④每个学生学习每一一门课程有一个成绩。
于是得到属性组U上的一组函数依赖F
F={Sno- > Sdept, Sdept- >Mname, (Sno, Cno)- >Grade}
(如图所示)
这个关系模式设计的并不好,存在以下问题:
鉴于存在以上种种问题,可以得出这样的结论:
Student关系模式不是一个好的模式
。“好”的模式:
某些数据依赖
引起的分解关系模式
来消除其中不合适 的数据依赖
可以把这个单一模式分成3个关系模式:
S(Sno,Sdept,Sno → Sdept);
SC(Sno,Cno,Grade,(Sno,Cno) → Grade);
DEPT(Sdept,Mname,Sdept→ Mname)
这三个模式都不会发生插入异常、删除异常的问题,数据的冗余也得到了控制。
一个模式的数据依赖会有哪些不好的性质,如何改造一个不好的模式
,这就是接下来2.规范化
要讨论的内容。
规范化讨论如何根据属性间依赖情况来判定关系是否具有某些不合适的性质
通常按属性间依赖情况来区分关系规范化程度
为第一范式、第二范式、第三范式和第四范式等
用来改造关系模式,通过分解关系模式来消除其中不合适的数据依赖,以解决插入异常、删除异常、更新异常和数据冗余问题。
函数依赖
码
范式
2NF
3NF
BCNF
多值依赖
4NF
其中函数依赖、码是为了学习范式、1NF,2NF,3NF……打基础
注意:
函数依赖不是指关系模式R的某个或某些关系满足的约束条件,而是指R的一切关系均要满足的约束条件。
以下是一个错误的例子:
sno->sdept,sno应该唯一决定sdept
函数依赖和别的数据依赖样是语义范畴的概念,只能根据语义来确定一个函数依赖。
例如,姓名→年龄这个函数依赖只有在该部门没有同名人的条件下成立。如果允许有同名人,则年龄就不再函数依赖于姓名了。
直接依赖这里我们举个例子:
BH(sno,idCard,address)
X:sno 学号
Y:idCard 身份证号
Z:address 住址
X->Y,Y->X,X<->Y,Y->Z
所以我们说Z直接依赖于X
例题:
例1:关系模式CTHRSG, 若最小依赖集为F’={C →T, HR →C,CS →G,HS →R,HT →R}
解:L、N类属性为HS,LR属性为CTR。HS+=HS RCTG,包含全部属性,所以为唯一候选码
例2:
解:L或N类属性有E和C, LR类属性ADB,令X=EC,(EC)+=U,EC为R的唯一候选码。
例3:
例4:
例5:
主属性与非主属性
主属性(Prime attribute)
非主属性(Nonprime attribute)
或非码属性(Non-key attribute)
举几个例子:
[例2]
关系模式S(Sno,Sdept,Sage),单个属性Sno是码
,
SC(Sno,Cno,Grade)中,(Sno,Cno)是码
[例3]
关系模式R(P,W,A)
P:演奏者 W:作品 A:听众
一个演奏者可以演奏多个作品
某一作品可被多个演奏者演奏
听众可以欣赏不同演奏者的不同作品
码为(P,W,A),即All-Key
范式的种类:
各种范式之间存在联系:
R为第n范式
,可简记为R∈nNF。
模式分解
可以转换为若干个高一级范式的关系模式的集合,这种过程就叫规范化
1NF的定义:
不可分的基本数据项
,则R∈1NF
以下是一个满足1NF,但不是好的关系模式的例子:
关系模式 S-L-C(Sno, Sdept, Sloc, Cno, Grade)
Sloc为学生住处,假设每个系的学生住在同一个地方
图形化表示:
S-L-C不是一个好的关系模式,一个关系模式 R不属于2NF,就会产生以下几个问题:
插入异常
。假若要插入一个学生Sno=S7, Sdept =PHY, Sloc =BLD2, 但该生还未选课,即这个学生无Cno
,这样的元组就插不进S-L-C中。因为插入元组时必须给定码值,而这时码值的一部分 为空,因而学生的固有信息无法插入。
删除异常
。假定某个学生只选一门课,如S4就选了一门课C3,现在C3这门课他也不选了,那么C3这个数据项就要删除。而C3是主属性,删除了C3,整个元组就必须一起删除,使得S4的其他信息也被删除了
,从而造成删除异常,即不应删除的信息也删除了。修改复杂
。某个学生从数学系(MA)转到计算机科学系(CS),这本来只需修改此学生元组中的Sdept分量即可,但因为关系模式S-L-C中还含有系的住处Sloc属性,学生转系将同时改变住处,因而还必须修改元组中的Sloc分量。另外,如果这个学生选修了k门课,Sdept、 Sloc重复存储了k次,不仅存储冗余度大
,而且必须无遗漏地修改k个元组中全部Sdept、Sloc 信息,造成修改的复杂化
。为什么会有这些问题呢?
部分函数依赖于码
。分解为两个关系模式
,以消除这些部分函数依赖
解决方法:
分解
为两个关系模式,以消除传递函数依赖
:分解后的关系模式S-D与D-L中不再存在传递依赖
在一定程度上解决原2NF关系中存在的插入异常、删除异常、数据冗余度大、修改复杂等问题。
3NF
的关系后,仍然不能完全消除关系模式中的各种异常情况和数据冗余。
BCNF ( Boyce Codd Normal Form)是由Boyce与Codd提出的,比上述的3NF又进了一步,
通常认为BCNF是修正的第三范式,有时也称为扩充的第三范式。
下面用几个例子说明属于3NF的关系模式有的属于BCNF,但有的不属于BCNF。
[例5] 关系模式C(Cno,Cname,Pcno)
C∈3NF
C∈BCNF
关系模式C(Cno, Cname, Peno), 它
只有一个码Cno, 这里没有任何属性对Cno部分依赖或传递依赖,所以C∈3NF。
同时C中Cno
是唯一的决定因素
, 所以C ∈BCNF。
[例6]关系模式S(Sno, Sname, Sdept, Sage)
假定S有两个码Sno,Sname
S∈3NF。
S ∈ BCNF
假定Sname也具有唯一性, 那么S就有两个码,这两个码都由单个属性组成,彼此不相交。其他属性不存在对码的传递依赖与部分依赖,所以S∈3NF。
同时S中除Sno、Sname外没有其他决定因素
,所以S也属于BCNF。
[例7]关系模式SJP(S,J,P)
SJP∈3NF,
SJP∈BCNF
[例6.7]关系模式SJP(S, J, P)中,S是学生,J表示课程,P表示名次。
每一个学生选修每门课程的成绩有一定的名次,
每门课程中每一名次只有一个 学生(即没有并列名次)。
由语义可得到下面的函数依赖:
(S,J)→P; (J,P)→S
所以(S,J) 与(J,P)都可以作为候选码
。
这两个码各由两个属性组成,而且它们是相交的。
这个关系模式中显然没有属性对码传递依赖或部分依赖。
所以SJP∈3NF,而且除(S,J)与(J,P)以外没有其他决定因素,所以SJP∈BCNF。
[例8] 关系模式STJ(S, T, J)中,S表示学生,T表示教师,J表示课程。
每一教师只教一门课,
每门课有若干教师,
某一学生选定某门课, 就对应一个固定的教师。
由语义可得到如下的函数依赖。
(S,J)→T,(S,T)-J, T→J
函数依赖
关系可以用如图表示
这里(S,J)、 (S,T)都是候选码
。
STJ是3NF,因为没有任何非主属性对码传递依赖或部分依赖
,
但STJ不是BCNF关系
,因为T是决定因素,而T不包含码。
BCNF
,那么在函数依赖范畴内它已实现了彻底的分离,已消除了插入和删除的异常。
3NF的“不彻底”性
表现在可能存在主属性对码
的部分依赖
和传递依赖
。用一个例子引入多值依赖:
[例9] 学校中某一门课程由多个教师讲授,他们使用相同的一套参考书。每个教员可以讲授多门课程,每种参考书可以供多门课程使用。
可以用一个非规范化的关系来表示教师T、课程C和参考书B之间的关系
把这张表变成一张规范化的二维表:
码是(C, T, B)
,即all-key
,因而Teaching∈BCNF。
某一课程(如物理)增加一名讲课教师(如周英)时
,必须插入多个(这里是三个)元组:普通物理学
),(物理,周英,光学原理
),(物理,周英,物理习题集
)。某一门课(如数学)要去掉一本参考书(如微分方程)
,则必须删除多个(这里是两个)元组:李勇
,微分方程
),(数学,张平
,微分方程
)。多值依赖
(Multi-Valued Dependency, MVD)的数据依赖。例如,在关系模式Teaching中,对于一个(物理,光学原理)有一组T值{李勇,王军},这组值仅仅决定于课程C上的值(物理)。
也就是说对于另一个(物理,普通物理学),它对应的一组T值仍是{李勇,王军},尽管这时参考书B的值已经改变了。
因此T多值依赖于C,即C→→T
。
W→→S
。W→→C
成立。多值依赖具有以下性质:
关系模式R中的属性全是属性
任何二元关系模式中的最高范式必定是 BCNF
·概念的单一化·
关系模式规范化的基本步骤:
一、Armstrong公理系统设关系模式R,其中U为属性集,F是U上的一组函数依赖,那么有如下推理规则:
根据上面三条推理规则,又可推出下面三条推理规则:
引理:X→A1A2…Ak成立的充分必要条件是X→Ai成立(i=1,2,…,k)。
有效性是指由F出发根据Armstrong公理推导出来的函数依赖一定在F的闭包中。
完备性是指F的闭包中的每一个函数依赖,一定可以由F出发通过Armstrong公理推导出来
因此根据有效性和完备性→引理: 设F为属性集U上的一组函数依赖,X、Y⊆U,X→Y能由F根据Armstrong推导出来的充要条件是Y⊆F的闭包。
简单来说,属性闭包X+指的就是 所有X可以决定的属性的集合
我们也可以用属性闭包判断 X - > Y 是否蕴含于F
(1)求A+,先把A所决定的所有的属性依次扫描:
A+=A
A0=AB (因为有A -> B存在,所以A决定了B,就把B和A放在一起)
A1=ABC (由于A0=AB, AB中的B又决定了C(B->C),所以我们把C也加入属性闭包的集合中)
ABC没有可以决定的属性了,因此最终A+=ABC
(2)求属性集AD的闭包(AD+)
这道题和(1)题同理,
首先看F中是否有AD直接决定的属性,看了一下,发现没有 AD-> a 的情况存在
然后,我们考虑AD中的A或D是否有直接决定的属性,扫描一下,发现有!
AD+=AD
AD0=ADB (因为有A->B,所以把B加入属性闭包)
AD1=ADBC (因为第二项是B->C,所以把C也加入属性闭包)
因此最后 AD+ = ADBC
文字化表述,如何求闭包
举例子:有关系模式R,U={A,B,C,D,E},F={AB→C,B→D,C→E,EC→B,AC→B},求AB的闭包
①要求AB的闭包,因此先找出来函数依赖F中,左侧包含AB或者A、B的函数依赖:AB→C,B→D。
②令X(0)=AB,Y=CD(根据①的右侧推导),X(1)=X(0)∪Y=ABCD(左侧与右侧的并集)
③进行检验X(0)=X(1)?不等于。继续找左侧为ABCD子集(例如ABC、AC、C)的函数依赖:C→E、AC→B。
④再次进行X(2)=X(1)∪BE=ABCDE
⑤进行检验X(0)=X(2)?也不等于,但是X(2)=U。因此结束,AB的闭包为ABCDE。
因此判断条件有两个就是①是X(0)=X(i) ②是X(2)=U
- 分解具有无损连接性
- 分解要保持函数依赖
- 分解既要保持函数依赖,又要保持无损连接性
已知R,U={A,B,C,D,E},F={A→C,B→C,C→D,DE→C,CE→A},R的一个分解为R1(AD),R2(AB),R3(BE),R4(CDE),R5(AE),判断这个分解是否具有无损连接性。
数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求。
数据库设计的基本步骤
需求分析和概念设计独立于任何数据库管理系统
逻辑设计和物理设计与选用的DBMS密切相关
需求分析是整个数据库设计过程中最重要的步骤之一,是后继各阶段的基础。在需求分析阶段,从多方面对整个组织进行调查,收集和分析各项应用对信息和处理两方面的需求。
收集资料是数据库设计人员和用户共同完成的任务。确定企业组织的目标,从这些目标导出对数据库的总体要求。通过调研,确定由计算机完成的功能。
分析的过程是对所收集到的数据进行抽象的过程,产生求解的模型。
采用数据流图来描述系统的功能。数据流图可以形象地描述事务处理与所需数据的关联,便于用结构化系统方法,自顶向下,逐层分解,步步细化。
对数据流图中的数据流和加工等进一步定义,从而完整地反映系统需求。
数据字典的用途:
进行详细的数据收集和数据分析所获得的主要结果
数据字典的内容:
数据项
数据结构
数据流
数据存储
处理过程
第一阶段收集的基础数据用数据字典来描述
需求分析得到的数据流图和数据字典要返回给用户,通过反复完善,最终取得用户的认可。
概念设计阶段的目标是产生整体数据库概念结构,即概念模式。概念模式是整个组织各个用户关心的信息结构。描述概念结构的有力工具是 E-R 模型。
E-R数据模型是一个广泛用于数据库设计的数据模型,提供了一个方便的图形化表示方法以查看数据、联系和约束。
实体-联系(entity-relationship, E-R)模型采用三个基本概念:实体集、联系集、属性。
数据库包括一组实体集,每个实体集包括任意数量的相同类型的实体。
实体是在现实世界中存在并且区别于其他对象的对象。我们通过把每个实体痛描述该实体的一组属性相关联来表示区别。相同类型的实体的集合为实体集。
联系是多个实体间的关联。相同类型的联系的集合为联系集。
**联系(relationship):**多个实体间的相互关联。
**联系集(relationship set):**相同类型联系的集合。
联系集是n≥2个(可能相同的)实体集上的数学关系。联系集R是
{ (e1, e2, …, en) | e1∈E1, e2∈E2, …, en∈En } 的一个子集,其中E1, E2, …, En为实体集,(e1, e2, …, en)为一个联系。
**参与:**实体集之间的关联。(e.g. 实体集E1, E2, …, En参与(participate)联系集R。)
相同的实体集可能会参与到多于一个联系集中。
二元(binary)联系集:设计两个实体集的联系集。数据库系统中的大部分联系集都是二元的,有时联系集会涉及多于两个实体集。
**度(degree):**参与联系集的实体集的数目称为联系集的度。(e.g. 二元联系集的度为2,3元联系集的度为3。)
**角色(role):**实体在联系中扮演的功能称为实体的角色。(隐含,一般并不指定。)
在自环(recursive,i.e. 同样的实体集以不同角色参与一个联系集多于一次)联系集中,有必要使用显式的角色名指明实体是如何参与联系实例的。
联系也可具有描述性属性(descriptive attribute)。(e.g. 实体集instructor和student之间的联系集advisor,可将属性date作为描述性属性与该联系关联。)
**联系实例(relationship instance):**E-R模式中的一个联系实例表示所在建模的现实世界企业中命名实体的一个关联。(e.g. 一个教师ID为45565的instructor实体Katz和一个学生ID为12345的student实体Shankar参与到advisor的一个联系实例中)
给定的联系集中的一个联系实例必须是由其参与实体唯一标识的(不必使用描述属性)。
**域(domain)/值集(value set):**每个属性都有的一个可取值的集合。
实体集的属性是将实体集映射到域的函数,每个实体可以用一组(属性,数据值)对来表示。
E-R模型中的属性可进行如下划分:
·简单(simple)属性/复合(composite)属性:
简单属性不能划分为更小的部分;
复合属性可以划分为更小的部分(其他属性)。(e.g. 属性name可设计为一个包括first_name、middle_initial和last_name的复合属性) 复合属性可以有层次,子属性可进一步划分。
·单值(single-alued)属性/多值(mutivalued)属性:
单值属性对一个特定的实体都只有单独的一个值;
多值属性对一个特定的实体有对应的一组值。用花括号表示属性是多值的。(e.g. instructor实体集可有{ phone_number }属性,每个教师可以有0到多个电话号码。) 可对多只属性的取值数目设置上、下界。
·派生(derived)属性:可从别的相关属性或实体派生出来。(e.g. instructor实体集可有属性student_advised表示一个教师指导了多少个学生,可通过统计与一个教师相关联的所有student实体的数目来得到该属性的值) 派生属性的值不进行存储,而是在需要时计算出来。
基属性:存储的属性
1. 映射基数
**映射基数(mapping cardinality)/基数比率:**表示一个实体通过一个联系集能关联的实体的个数。(可用于描述二元联系集和涉及多于两个实体集的联系集)
对于实体A和B之间的二元联系集R,映射基数必然是以下情况之一:
·一对一(one-to-one):A中的一个实体至多与B中的一个实体相关联,B中的一个实体也至多与A中的一个实体相关联;
·一对多(one-to-many):A中的一个实体可与B中任意数目(0到多个)实体相关联,B中的一个实体至多与A中的一个实体相关联;
·多对一(many-to-one):A中的一个实体至多与B中的一个实体相关联,B中的一个实体可与A中任意数目实体相关联;
·多对多(many-to-many):A中的一个实体可与B中任意数目实体相关联,B中的一个实体可与A中任意数目实体相关联。
2. 参与约束
如果实体集E中的每个实体都参与到联系集R的至少一个联系中,实体集E在联系集R中的参与称为全部的(total);
如果实体集E中只有部分实体参与到联系集R的联系中,实体集E到联系集R的参与称为部分的(partial)。
分割为两部分的矩形:代表实体集。第一部分(有阴影)包含实体集的名字,第二部分包含实体集中所有属性的名字;
菱形:代表联系集;
未分割的矩形:代表联系集的属性。构成主码的属性以下划线标明;
线段:将实体集连接到联系集;
虚线:将联系集属性连接到联系集;
双线:显示实体在联系集中的参与度;
双菱形:代表连接到弱实体集的标志性联系集。
E-R 模型通过 E-R 图表示出来。
将所有实体属性和实体之间的联系均描述出来就构成了一个 E-R 图
(2)基本 E-R 模型的扩展
数据抽象
一般有 3 种抽象:
(1)分类: 它抽象了对象值和型之间“is member of”的语义。例如:“张英”是“学生”实体中的一员。
(2)聚集 :它抽象了对象内部类型和成分之间“is part of”的语义。例如:若干属性的聚集组成了实体型。
(3)概括 :它抽象了类型之间“is subset of”的语义。
依赖联系
在现实世界中,常常有某些实体对于另一些实体具有很强的依赖关系,即一个实体的存在必须以另一实体的存在为前提。通常把前者称为弱实体。
在E-R图中,用双线框表示弱实体,用指向弱实体的箭头表明依赖联系。
超类和子类
概括定义了类型之间的一种子集联系。
例如:学生是一个实体型,本科生、研究生也是实体型。本科生、研究生均是学生的子集。把学生称为超类,本科生、研究生称为学生的子类。
在E-R图中,用双竖边的矩形框表示子类,用直线加小圆圈表示超类-子类联系。
子类继承超类上定义的全部属性,其本身还可包含其他属性。
UML是一种常用的建模语言。UML类图广泛用于对类建模以及一般的数据建模。
**对象:**UML类图为对象建模,对象类似实体,包含属性和方法。类图可以说明对象的属性和方法。
**方法:**UML类图中另外提供的一组函数,可在对象属性的基础上调用以计算值,或更新对象本身。
UML类图不支持复合或多值属性,派生属性与不带参数的函数等价;
UML类图支持封装,允许函数和属性带有前缀”+”、”-“或”#”,分别表示公共、私有以及受保护的访问。私有属性只能在类的方法中使用,受保护的属性只能在类和它的子类的方法中使用。
- 关联(association):在UML类图中联系集称为关联。通过画一条线段连接实体集表示二元联系集,联系集的名称写在线段附近。可用以下两种方式说明联系集:
a. 可将角色名称写在靠近实体集的线段上,说明联系集中一个实体集的角色;
b. 可将联系集的名字和属性一起写在方框里,用虚线将该方框连接到表示联系集的连线上。该方框可看作一个实体集,可与其他实体一起参与联系。
**统一建模语言(Unified Modeling Language, UML):**为建立软件系统的不同部分的规范定义而提出的一个标准。组成部分包括
UML中使用l…h形式表示基数约束,i表示参与联系的实体的最小个数,h表示最大个数。但约束位置与E-R图中正好相反。
e.g.
E2边上的约束0…*和E1边上的0…1表示每个E2实体可以参与至多一个联系,而每个E1实体可以参与任意多的联系,即该联系是从E2到E1多对一的。
可将单个值(如1或*)卸载边上,单个值1等价1…1,单个值等价0…。
UML类图支持概化,与E-R图基本相同,包括不想交概化和重叠概化的表示方式。
UML类图还包含一些与E-R表示法并不对应的表示法。
e.g. 连接两个实体的一条线的一端有一个小菱形,表示菱形这一端的实体集包含另一个实体集(e.g. 一个车辆实体可能包含一个发动机实体)。(包含关系在UML中称为”聚合“,注意不应与E-R图中的聚合的含义混淆。)
UML类图还提供表示面向对象语言的特征的表示法(e.g. 接口)。
(1)设计局部 E-R 模型
确定局部结构范围
定义实体
联系定义
属性分配
(2)设计全局 E-R 模型
确定公共实体类型
局部E-R模型的合并
消除冲突
(3)全局 E-R 模型的优化
实体类型的合并
冗余属性的消除
冗余联系的消除
逻辑结构设计就是把上述概念模型转换成为某个具体的数据库管理系统所支持的数据模型。
转换原则:
(1)每一个实体类型转换为一个关系模式,实体的属性就是关系的属性,实体的码就是关系的码。
(2)联系的转换
① 一般1:1,1:m联系不产生新的关系模式,而是将一方实体的码加入到多方实体对应的关系模式中,联系的属性也一并加入。
②m:n联系要产生一个新的关系模式,该关系模式由联系涉及实体的码加上联系的属性(若有)组成。
具体做法:
一个 1:1 联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,每个实体的码均是该关系的候选码。如果与某一端实体对应的关系模式合并,则需要在该关系模式的属性中加入另一个关系模式的码和联系本身的属性。可将任一方实体的主码纳入另一方实体对应的关系中,若有,联系的属性也一并纳入。
例如,如图 6.1 所示的 E-R 图可转换为如下关系模式:
工厂(厂号,厂名,地点,姓名,任期)
厂长(姓名,性别,年龄)
或者:
工厂(厂号,厂名,地点)
厂长(姓名,性别,年龄,厂号,任期)
可将“1”方实体的主码纳入“m”方实体对应的关系中作为外码,同时把联系的属性也一并纳入“m”方对应的关系中。
例如,如图 6.2 所示的 E-R 图转换为如下关系模式:
仓库(仓库号,地点,面积)
商品(货号,品名,价格,仓库号,数量)
可在这个实体所对应的关系中多设一个属性,作为与该实体相联系的另一个实体的主码。
例如,如图 6.3 所示的 E-R 图可转换为如下关系模式:
职工(工号,姓名,年龄,性别,职称,工资,领导者工号,民意测验)
可将被依赖实体的主码纳入弱实体中,作为弱实体的主码或主码中的一部分。
例如,如图 6.4 所示的 E-R 图可转换为如下关系模式:
职工(工号,姓名,年龄,性别,职称)
亲属(工号,亲属姓名,亲属关系)
超类、子类实体都可转换为一个关系,并将超类实体的主码加到子类实体中。
例如,如图 6.5 所示的 E-R 图中各个实体的属性为:
职员:职工号,姓名,性别,年龄,参加工作时间
飞行员:飞行小时,健康检查,飞机型号
机械师:学历,级别,专业职称
管理员:职务,职称
该 E-R 图转换为如下关系模式:
职员(职工号,姓名,性别,年龄,参加工作时间)
飞行员(职工号,飞行小时,健康检查,飞机型号)
机械师(职工号,学历,级别,专业职称)
管理员(职工号,职务,职称)
为了查询方便,可在超类实体中增加一个指示器属性,根据指示器的值直接查询子类实体表。所以,职员关系又可以为:
职员(职工号,姓名,性别,年龄,参加工作时间,职员类型)
必须对“联系”单独建立一个关系,该关系中至少包含被它所联系的双方实体的“主码”,如果联系有属性,也要纳入这个关系中。
例如,如图 6.6 所示的 E-R 图转换为如下关系模式:
学生(学号,姓名,性别,年龄)
课程(课程号,课程名,学时)
选修(学号,课程号,成绩)
必须为这个“联系”单独建立一个关系,该关系中至少应包含被它所联系的双方实体的“主码”,如果联系有属性,也要纳入这个关系中。由于这个“联系”只涉及一个实体,所以加入的实体的主码不能同名。
例如,如图 6.7 所示的 E-R 图转换为如下关系模式:
零部件(代号,名称,价格)
组装(代号,组装件代号,数量)
必须为这个“联系”单独建立一个关系,该关系中至少应包含被它所联系的各个实体的“主码”,若是联系有属性,也要纳入这个关系中。
例如,如图 6.8 所示的 E-R 图可转换为如下关系模式:
供应商(供应商号,供应商名,地址)
零件(零件号,零件名,重量)
项目(项目编号,项目名称,开工日期)
供应(供应商号,项目编号,零件号,零件数)
最核心的就是要遵循数据库设计的nF范式
应用关系规范化理论对上述产生的关系模式进行优化,具体步骤如下:
(1)确定每个关系模式内部各个属性之间的数据依赖以及不同关系模式属性之间的数据依赖。
(2)对各个关系模式之间的数据依赖进行最小化处理,消除冗余的联系。
(3)确定各关系模式的范式等级。
(4)按照需求分析阶段得到的处理要求,确定要对哪些模式进行合并或分解。
(5)为了提高数据操作的效率和存储空间的利用率,对上述产生的关系模式进行适当的修改、调整和重构。
全局关系模型设计完成后,还应根据局部应用的需求,结合具体 DBMS 的特点,设计用户的子模式。
设计子模式时应注意考虑用户的习惯和方便性,主要包括:
(1)使用更符合用户习惯的别名。
(2)可以为不同级别的用户定义不同的视图,以保证系统的安全性。
(3)可将经常使用的复杂的查询定义为视图,简化用户对系统的使用。
一、DML
DML(data manipulation language)数据操纵语言:
就是我们最经常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用来对数据库的数据进行一些操作。
SELECT 列名称 FROM 表名称
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
DELETE FROM 表名称 WHERE 列名称 = 值
二、DDL
DDL(data definition language)数据库定义语言:
其实就是我们在创建表的时候用到的一些sql,比如说:CREATE、ALTER、DROP等。DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上
CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
)
ALTER TABLE table_name
ALTER COLUMN column_name datatype
DROP TABLE 表名称
DROP DATABASE 数据库名称
三、DCL
DCL(Data Control Language)数据库控制语言:
是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。这个比较少用到。
数据库的物理设计是指对一个给定的逻辑数据库模型选取一个最适合应用环境的物理结构的过程。物理设计通常分为两步:
(1)确定数据的存取方法
(2)确定数据的存储结构
对时间效率、空间效率、维护开销和各种用户要求进行权衡,从多种设计方案中选择一个较优的方案。
评价方法(完全依赖于所选用的DBMS )
实施阶段的工作主要有:
功能测试
性能测试
数据库系统投入正式运行后,对数据库经常性的维护工作主要由 DBA 完成,包括:
重组织的目标
重组织的工作
数据库重构造
UML类图还包含一些与E-R表示法并不对应的表示法。
e.g. 连接两个实体的一条线的一端有一个小菱形,表示菱形这一端的实体集包含另一个实体集(e.g. 一个车辆实体可能包含一个发动机实体)。(包含关系在UML中称为”聚合“,注意不应与E-R图中的聚合的含义混淆。)
UML类图还提供表示面向对象语言的特征的表示法(e.g. 接口)。
(1)设计局部 E-R 模型
确定局部结构范围
定义实体
联系定义
属性分配
(2)设计全局 E-R 模型
确定公共实体类型
局部E-R模型的合并
消除冲突
(3)全局 E-R 模型的优化
实体类型的合并
冗余属性的消除
冗余联系的消除
逻辑结构设计就是把上述概念模型转换成为某个具体的数据库管理系统所支持的数据模型。
[外链图片转存中…(img-NCLoNSWU-1648358301109)]
转换原则:
(1)每一个实体类型转换为一个关系模式,实体的属性就是关系的属性,实体的码就是关系的码。
(2)联系的转换
① 一般1:1,1:m联系不产生新的关系模式,而是将一方实体的码加入到多方实体对应的关系模式中,联系的属性也一并加入。
②m:n联系要产生一个新的关系模式,该关系模式由联系涉及实体的码加上联系的属性(若有)组成。
具体做法:
一个 1:1 联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,每个实体的码均是该关系的候选码。如果与某一端实体对应的关系模式合并,则需要在该关系模式的属性中加入另一个关系模式的码和联系本身的属性。可将任一方实体的主码纳入另一方实体对应的关系中,若有,联系的属性也一并纳入。
例如,如图 6.1 所示的 E-R 图可转换为如下关系模式:
工厂(厂号,厂名,地点,姓名,任期)
厂长(姓名,性别,年龄)
或者:
工厂(厂号,厂名,地点)
厂长(姓名,性别,年龄,厂号,任期)
[外链图片转存中…(img-P2EuKItj-1648358301110)]
可将“1”方实体的主码纳入“m”方实体对应的关系中作为外码,同时把联系的属性也一并纳入“m”方对应的关系中。
例如,如图 6.2 所示的 E-R 图转换为如下关系模式:
仓库(仓库号,地点,面积)
商品(货号,品名,价格,仓库号,数量)
[外链图片转存中…(img-WAlMgVRt-1648358301111)]
可在这个实体所对应的关系中多设一个属性,作为与该实体相联系的另一个实体的主码。
例如,如图 6.3 所示的 E-R 图可转换为如下关系模式:
职工(工号,姓名,年龄,性别,职称,工资,领导者工号,民意测验)
[外链图片转存中…(img-aFNS7OJs-1648358301113)]
可将被依赖实体的主码纳入弱实体中,作为弱实体的主码或主码中的一部分。
例如,如图 6.4 所示的 E-R 图可转换为如下关系模式:
职工(工号,姓名,年龄,性别,职称)
亲属(工号,亲属姓名,亲属关系)
[外链图片转存中…(img-5UPILipZ-1648358301114)]
超类、子类实体都可转换为一个关系,并将超类实体的主码加到子类实体中。
例如,如图 6.5 所示的 E-R 图中各个实体的属性为:
职员:职工号,姓名,性别,年龄,参加工作时间
飞行员:飞行小时,健康检查,飞机型号
机械师:学历,级别,专业职称
管理员:职务,职称
该 E-R 图转换为如下关系模式:
职员(职工号,姓名,性别,年龄,参加工作时间)
飞行员(职工号,飞行小时,健康检查,飞机型号)
机械师(职工号,学历,级别,专业职称)
管理员(职工号,职务,职称)
为了查询方便,可在超类实体中增加一个指示器属性,根据指示器的值直接查询子类实体表。所以,职员关系又可以为:
职员(职工号,姓名,性别,年龄,参加工作时间,职员类型)
[外链图片转存中…(img-SX76PybW-1648358301115)]
必须对“联系”单独建立一个关系,该关系中至少包含被它所联系的双方实体的“主码”,如果联系有属性,也要纳入这个关系中。
例如,如图 6.6 所示的 E-R 图转换为如下关系模式:
学生(学号,姓名,性别,年龄)
课程(课程号,课程名,学时)
选修(学号,课程号,成绩)
[外链图片转存中…(img-HFdnNyWM-1648358301115)]
必须为这个“联系”单独建立一个关系,该关系中至少应包含被它所联系的双方实体的“主码”,如果联系有属性,也要纳入这个关系中。由于这个“联系”只涉及一个实体,所以加入的实体的主码不能同名。
例如,如图 6.7 所示的 E-R 图转换为如下关系模式:
零部件(代号,名称,价格)
组装(代号,组装件代号,数量)
[外链图片转存中…(img-RgK0ZkLf-1648358301116)]
必须为这个“联系”单独建立一个关系,该关系中至少应包含被它所联系的各个实体的“主码”,若是联系有属性,也要纳入这个关系中。
例如,如图 6.8 所示的 E-R 图可转换为如下关系模式:
供应商(供应商号,供应商名,地址)
零件(零件号,零件名,重量)
项目(项目编号,项目名称,开工日期)
供应(供应商号,项目编号,零件号,零件数)
[外链图片转存中…(img-tzWS1ieE-1648358301117)]
最核心的就是要遵循数据库设计的nF范式
应用关系规范化理论对上述产生的关系模式进行优化,具体步骤如下:
(1)确定每个关系模式内部各个属性之间的数据依赖以及不同关系模式属性之间的数据依赖。
(2)对各个关系模式之间的数据依赖进行最小化处理,消除冗余的联系。
(3)确定各关系模式的范式等级。
(4)按照需求分析阶段得到的处理要求,确定要对哪些模式进行合并或分解。
(5)为了提高数据操作的效率和存储空间的利用率,对上述产生的关系模式进行适当的修改、调整和重构。
全局关系模型设计完成后,还应根据局部应用的需求,结合具体 DBMS 的特点,设计用户的子模式。
设计子模式时应注意考虑用户的习惯和方便性,主要包括:
(1)使用更符合用户习惯的别名。
(2)可以为不同级别的用户定义不同的视图,以保证系统的安全性。
(3)可将经常使用的复杂的查询定义为视图,简化用户对系统的使用。
[外链图片转存中…(img-GdoXSBl9-1648358301118)]
一、DML
DML(data manipulation language)数据操纵语言:
就是我们最经常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用来对数据库的数据进行一些操作。
SELECT 列名称 FROM 表名称
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
DELETE FROM 表名称 WHERE 列名称 = 值
二、DDL
DDL(data definition language)数据库定义语言:
其实就是我们在创建表的时候用到的一些sql,比如说:CREATE、ALTER、DROP等。DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上
CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
)
ALTER TABLE table_name
ALTER COLUMN column_name datatype
DROP TABLE 表名称
DROP DATABASE 数据库名称
三、DCL
DCL(Data Control Language)数据库控制语言:
是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。这个比较少用到。
数据库的物理设计是指对一个给定的逻辑数据库模型选取一个最适合应用环境的物理结构的过程。物理设计通常分为两步:
[外链图片转存中…(img-VnDxRSfE-1648358301119)]
(1)确定数据的存取方法
(2)确定数据的存储结构
对时间效率、空间效率、维护开销和各种用户要求进行权衡,从多种设计方案中选择一个较优的方案。
评价方法(完全依赖于所选用的DBMS )
实施阶段的工作主要有:
功能测试
性能测试
数据库系统投入正式运行后,对数据库经常性的维护工作主要由 DBA 完成,包括:
重组织的目标
重组织的工作
数据库重构造