数据库系统的基本概念
数据库是数据管理的有效技术,是计算机科学的重要分支。如今,信息资源已成为各个部门的重要财富和资源。信息积累形成数据库,应用数据库可以实现积累的效益,对数据库的管理和控制就显得极为重要,所以数据库是一门技术,更是一种思维。
什么是数据、数据库、数据库管理系统、数据库系统?
-
数据(Data):描述事物的符号记录。Ex:描述事物的符号可以是数字、文字、图像、音频等,它们经数字化后可存入电脑。
-
数据库(Data Base,DB):长期存储在计算机内,有组织的、可共享的大量数据集合。
-
数据库管理系统(DataBase Management System,DBMS):是一个管理数据库的系统软件,用来科学地组织和存储数据,高效地获取和维护数据。
-
数据库管理员(DataBase Administrator,DBA):建立、使用和维护数据库的工作人员。
-
数据库系统(DataBase System,DBS):由数据库、数据库管理系统、应用程序和数据库管理员组成的存储、管理、处理和维护数据的系统。
两类数据模型
两类数据模型,第一类是概念模型,第二类是逻辑模型和物理模型。
-
概念模型,也称为信息模型,它是按照用户的观点对数据和信息建模,主要用于数据库的设计。
-
逻辑模型,是按照计算机系统的观点对数据进行建模,主要用于数据库管理系统的实现。Ex:关系模型、层级模型、网状模型、面向对象数据模型、对象关系数据模型、半结构化数据模型。(层级模型和网状模型统称为格式化模型)
-
物理模型,是对数据最底层的抽象,它描述数据在系统内部的表示方法和存取方法,是面向计算机系统的。
三级模式、两层映像、两个独立性
-
三级模式——外模式、模式、内模式
-
两层映像——外模式-模式的映像(E-C Mapping)、模式-内模式的映像(C-I Mapping)
-
数据的逻辑独立性,当模式改变时(ex:增加新的关系、新的属性、改变属性的数据类型等),由数据库管理员对外模式/模式的映像作相应改变,可以使外模式保持不变。应用程序时依据数据的外模式编写的,从而应用程序不必修改,保证了数据与程序的逻辑独立性。
-
数据的物理独立性,当数据库的存储结构改变时(ex:选用了另一种存储结构),由数据库管理员对模式/内模式映像作相应改变,可以使模式保持不变,从而应用程序也不必改变,保证了数据的物理独立性。
数据模型vs模式vs数据
-
数据模型:规定模式统一描述方式的模型,包括:数据结构、操作和约束。
-
数据模型是对模式本身结构的抽象,模式是对数据本身结构形式的抽象。
Ex:关系模型:所有模式都可为抽象表的形式[数据结构],而每一个具体的模式都是拥有不同列名的具体的表。对这种表形式的数据有哪些[操作]和[约束]。
数据库中的范式、三大范式是什么?
关系数据库中的关系满足一定的要求,满足不同程度的要求的是不同的范式。满足最低要求的叫第一范式。
第一范式
所有属性不可再分,即数据项不可再分。
第二范式
某关系R属于第一范式,且每一个非主属性完全函数依赖于任何一个候选码。(****候选码:**** 若关系中的某一属性组的值能唯一地标识一个元组,而其子集不能,则称该属性组为候选码。若一个关系中有多个候选码,则选定其中一个为主码。)
Ex:第二范式指每一个表必须有一个(有且仅有一个)数据项作为关键字或主键,其他数据项与关键字或主键一一对应,即其他数据项依赖于主键。
第三范式
满足第二范式,且非主属性既不传递依赖于码,也不部分依赖于码。
Ex: 第三范式要求在满足第二范式的基础上,任何非主属性不依赖于其他非主属性,即在第二范式的基础上,消除了传递依赖。
关系模型的三个要素
基本结构
关系模型的数据结构只包含单一的数据结构——关系。在用户看来关系模型中数据的逻辑结构是一张二维表。
基本操作
并、差、广义积、选择、投影是5种基本操作,其他操作如交、连接、除可以用基本操作来定义和导出,就像乘法可以用加法来定义和导出一样。
完整性约束
关系模型中有三类完整性约束:实体完整性、参照完整性和用户定义的完整性。(其中实体完整性和参照完整性是关系模型必须满足的完整性约束条件,被称作是关系的两个不变性。)
关系上的一些重要概念
候选码/候选键
关系中的一个属性组,其值能唯一标识一个元组,若从该属性组中去掉任何一个属性,它就不具有这一性质了,这样的属性组称作候选码(Candidate Key)。
Ex1:“学生(S#,Sname,Sage,Sclass)”,S#就是一个候选码,在此关系中,任何两个元组S#是一定不同的,而这两个元组的Sname,Sage,Sclass都可能相同(同名、同龄、同班),所以S#是候选码。
Ex2:“选课(S#,C#,Sname,Gname,Grade)”,(S#,C#)联合起来是一个候选码。
主码/主键
当有多个候选码时,可以选定一个作为主码。DBMS以主码为主要线索管理关系中的各个元组。
Ex:可选定属性S#作为“学生”表的主码。也可以选定属性组(Sname,Saddress)作为“学生”表的主码(Primary Key)。
主属性与非主属性
包含在任何一个候选码中的属性被称为主属性,而其他属性被称为非主属性。
Ex:“选课”中的“S#,C#”为主属性,而Sname,Gname,Grade则为非主属性。
外码/外键
关系R中的一个属性组,它不是R的候选码,但它与另一个关系S的候选码对应,则成为这个属性组为R的外码或外键(Foreign Key)。
Ex:下图“合同”关系中的客户号不是候选码,但却是外码。因为它与“客户”关系中的候选码“客户号”相对应。(两个或多个关系通常是考外码连接起来的)。
关系vs表
- 关系是对表进行的严格定义,关系和表是有差别的。
- 关系是严格的数学含义,是没有重复的元组;表是以按行按列形式组织及展现的数据,可以由重复的元组的。
- 关系数据库理论中用关系来描述;商用系统数据库中都是以表来进行表达。
书写关系代数表达式的基本思路
1.检索是否涉及多个表,如不涉及,则可直接采用并、差、交、选择与投影,只要注意条件书写正确与否即可。
2.如涉及多个表,则检查
能否使用自然链接,将多个表连接起来(多数情况是这样的)
如不能,能否使用等值或不等值连接(θ-连接)
还不能,则使用广义笛卡儿积,注意相关条件的书写
3.连接完后,可以继续使用选择、投影等运算,即所谓数据库的“选连投”操作
关系运算
关系运算有三种:关系代数、关系元组演算、关系域演算。三种关系运算都是抽象的数学运算,体现了三种不同的思维。
关系代数,以集合为对象的操作思维,由集合到集合的变换。
元组演算,是以元组为对象的操作思维,取出关系的每一个元组进行验证,有一个元组变量则可能需要一个循环,多个元组变量则需要多个循环。
域演算,是以域变量为对象操作思维,取出域的每一个变量进行验证看其是否满足条件。
SQL语言之概述
结构化查询语言(SQL,Structured Query Language)是关系数据库的标准语言。
SQL语言的功能概述
SQL语言是集DDL(数据定义语言,用于定义数据库、数据表)、DML(数据操纵语言,用于操纵数据库中的数据)、DCL(数据控制语言,用于控制哪些数据库、表、数据可以被哪些用户访问,不可以被哪些用户访问)于一体的数据库语言。
-
DDL语言引导词:Create(建立),Alter(修改),Drop(撤消)
模式的定义和删除,包括定义Database,Table,View,Index,完整性约束,也包括定义对象(RowType行对象,Type列对象)
-
DML语言引导词:Insert,Delete,Update,Select
各种方式的更新与检索操作,如直接输入记录,从其他Table(由SubQuery建立)输入。
各种复杂的检索,如连接查找,模糊查找,分组查找,嵌套查找等。
各种聚集操作,求平均、求和等,分组聚集,分组过滤等。
-
DCL语句引导词:Grant,Revoke
安全性控制:授权和撤销授权。
建立数据库包括两件事:定义数据库和表(使用DDL)、向表中追加元组(使用DML)
定义数据库(DDL)
创建数据库
数据库(Database)是若干具有相互关联关系的Table/Relation的集合,可以看作是一个集中存放若干Table的大型文件。
创建数据库的简单语法形式:
create database 数据库名;
ex:创建课程学习数据库SCT
create database SCT;
创建表
创建表的简单语法形式:
create table 表名(列名 数据类型[Primary Key | Unique] [Not null]
[,列名 数据类型 [Not null],…])
ex:定义学生表 Student
create table Student(S# char(8) not null,Sname char(10),Ssex char(2),
Sage integer,D# char(2),Sclass char(6))
注意:①“[ ]”表示其括起的内容可以省略,“ | ”表示其隔开的两项可取其一
②Primary Key:主键约束,每个表只能创建一个主键约束。
③Unique:唯一性约束(即候选键),可以有多个唯一性约束。
④Not null:非空约束,是指该列允许不允许有空值出现,如选择了Not null表明该列不允许有空值出现。
⑤语法中的数据类型在SQL标准中有定义
在SQL-92标准中定义的数据类型:
- char(n):固定长度的字符串
- varchar(n):可变长度的字符串
- int:整数 //有时不同系统也写作integer
- numeric(p,q):固定精度数字,小数点左边p位,右边p-q位
- real:浮点精度数字 //有时不同系统也写作float(n),小数点后面保留n位
- date:日期 (如:2003-9-12)
- time:时间 (如:22:12:52)
- …
操作数据库(DML)
向表中追加元组
插入的简单语法形式:
insert into 表名 [ (列名 [,列名]…) ] values(值 [,值],…);
ex:追加学生表中的元组
Insert into Student(S#,Sname,Ssex,Sage,D#,Sclass)values(‘9803012’,‘张三’、‘女’、20、‘03’、‘980301’)
利用SQL语言进行简单的查询
查询的简单语法:
select 列名 [[,列名]…] from 表名 [ where 检索条件]
ex:检索学生表中所有学生的姓名及年龄
Select Sname,Sage from student;
注意:①语意:从表名所给出的表中,查询出满足检索条件的元组,并按照给定的列名及顺序进行投影显示。相当于关系代数中选择与投影的组合。
②select语句中的select…,from …,where …等被称为子句,在以上基本形式的基础上会增加许多构成元素,也会增加许多新的子句,满足不同的需求。
检索条件的书写
与选择运算的条件con书写一样,只是其逻辑运算符用and,or,not来表示,同时也要注意运算符的优先次序及括号的使用。书写要点是注意对自然语言检索条件的正确理解。
ex:检索教师表中所有工资少于1500或者工资大于2000 并且是03系的教师姓名
Select Tname From Teacher where ( Salary<1500 or Salary>2000 ) and D#=‘03’
结果唯一性问题
关系模型不允许出现重复元组,但现实DBMS,却允许出现重复元组,但也允许无重复元组。
在Table中要求无重复元组是通过定义Primary Key或Unique来保证;而在检索结果中要求无重复元组,是通过DISTINCT保留字的使用来实现。
ex:在选课表中,检索成绩大于80分的所有学号
Select S# From SC Where Score>80 //有重复元组出现,比如一个同学有两门以上课程大于80
Select DISTINCT S# From SC Where Score>80 //重复元组被DISTINCT过滤掉,只保留一份
结果排序问题
DBMS可以对检索结果进行排序,可以升序排列,也可以降序排列。
Select语句中结果排序是通过order by子句实现:
order by 列名 [asc|desc]
意义为检索结果按指定列名排序,若后跟asc或者省略,则为升序;若后跟desc,则为降序。
ex:按学号由小到大的顺序显示出所有学生的学号及姓名
Select S#,Sname From Student Order By S# ASC;
模糊查询问题
比如检索姓张的学生,检索张某某,这类查询,Select语句是通过在检索条件中引入运算符like来表达的。
表达式为:
列名 [not] like “字符串”
注意:
①找出匹配给定字符串的字符串。其中给定字符串中可以出现%,_等匹配符。
②匹配规则:
“%” 匹配零个或多个字符。
“_” 匹配任意单个字符。
“\” 转义字符,用于去掉一些特殊字符的特定含义,使其被作为普通字符看待,如用“%”去匹配字符%,用“ \ _”去匹配 _。
ex:检索所有姓张的学生学号及姓名
Select S#,Sname From Student Where Sname Like ‘张%’;
利用SQL语言进行多表联合查询
多表联合检索可以通过连接运算来完成,而连接运算又可以通过笛卡儿积后再进行选择运算来实现。
Select的多表联合检索语句:
Select 列名 [ [,列名]… ] From 表名1,表名2,… Where 检索条件;
连接——等值连接
ex:按“001”号课成绩由高到低顺序显示所有学生的姓名(二表连接)
Select Sname From Student,SC Where Student.S#=SC.S# and SC.C#=‘001’ Order by Score DESC;
多表连接时,若两个表的属性名相同,则需要采用表名.属性名的方式来限定该属性属于哪一个表。
重名处理
连接运算涉及到重名的问题,如两个表的属性重名,连接的两个表重名(同一表的连接)等。因此需要使用别名以便于区分。
Select中采用别名的方式:
Select 列名 as 列别名 [ [,列名 as 列别名] …]
From 表名1 as 表别名1 ,表名2 as 表别名2,…
Where 检索条件;
注意:①上述定义的as可以省略
②当定义了别名后,在检索条件中可以使用别名来限定属性。
连接——不等值连接
ex:求有薪水差额的任意两位教师
Select T1.Tname as Teacher1,T2.Tname as Teacher2
From Teacher T1,Teacher T2
Where T1.Salary>T2,Salary;
利用SQL语言进行增-删-改
元组新增Insert:新增一个或一些元组到数据库的Table中。
元组更新Update:对某些元组中的某些属性值进行重新设定。
元组删除Delete:删除某些元组。
SQL-Insert
元组新增Insert命令有两种形式:
①单一元组新增命令形式:
insert into 表名 [(列名[,列名])] values (值[,值]…);
②批数据新增命令形式:
insert into 表名 [(列名[,列名])] 子查询;
ex:
单一元组新增:
insert into Teacher (T#,Tname,D#,Salary) Values(“005”,“张三”,“01”,“5000”);
批元组新增:
新建立Table:St(S#,Sname),将检索到的满足条件的同学新增到该表中
Insert into St(S#,Sname) Select S#,Sname From Student Where Sname like ‘%伟’;
注意:当新增元组时,DBMS会检查用户定义的完整性约束条件等,如不符合完整性约束的条件,则不会执行新增动作。
SQL-Delete
元组删除Delete命令:删除满足指定条件的元组
Delete From 表名 [Where 条件表达式];
ex:删除SC表中所有元组
Delete From SC;
SQL-Update
元组更新Update命令:用指定要求的值更新指定表中满足指定条件的元组的指定列的值。
Undate 表名 Set 列名=表达式 | (子查询) [ [,列名=表达式 | (子查询)]… ] [Where 条件表达式]
ex:将所有教师工资上调5%
Update Teacher Set Salary=Salary*1.05;
利用SQL语言修正和撤销数据库
修正数据库
修正数据库的定义,主要是修正表的定义。
修正基本表的定义:
altert table talename
[add {colname datetype,…}] //增加新列
[drop {完整性约束名}] //删除完整性约束
[modify {colname datetype,…}] //修改列定义
ex:删除学生姓名必须取唯一值得约束
Alter Table Student Drop Unique(Sname);
在学生表Student基础上增加两列Saddr,PID
Alter Table Student Add Saddr char[40],PID char[18];
撤销基本表
drop table 表名
ex:撤销学生表
Drop table Student;
撤销数据库
drop database 数据库名;
ex:撤销SCT数据库
Drop Database SCT;
SQL语言——复杂查询
为什么需要子查询?
现实中,很多情况需要进行下述条件的判断
- 集合成员资格,某一元素是否是某一个集合的成员。
- 集合之间的比较,某一个集合是否包含另一个集合等。
- 集合基数的测试,测试集合是否为空、测试集合是否存在重复元组。
子查询:出现在Where子句中的Select语句被称为子查询(subquery),子查询返回了一个集合,可以通过与这个歌集合的比较来确定另一个集合查询。三种类型的子查询:(Not)IN-子查询;θ Some/θ All 子查询;(not)EXIST子查询
IN子查询
基本语法:
表达式 [not] in (子查询)
语法中:表达式的最简单的形式就是列名或者常数。
语义:判断某一表达式的值是否在子查询的结果中。
ex:列出张三、王三同学的所有信息
Select * From Student Where Sname in(“张三”,“王三”);
列出选修了001号课程的学生的学号和姓名
Select S#,Sname From Student Where S# in (Select S# From SC Where C#=‘001’);
非相关子查询:内层查询独立进行,没有涉及外层查询相关信息的子查询。
相关子查询:内层查询需要依靠外层查询的某些参量作为限定条件才能进行的子查询,外层向内层传递的参量需要使用外层的表名或者表别名来限定。
θ Some/θ All 子查询
基本语法:
表达式 θ some (子查询)
表达式 θ all (子查询)
语义:将表达式的值与子查询的结果进行比较;语法中,θ是比较运算符:<,>,>=,<=,=,<>
EXISTS子查询
基本语法:
[not] Exists (子查询)
语义:子查询结果中有无元组存在。
聚集函数
SQL提供了五个作用在简单列值集合上的内置聚集函数agfunc,分别是:COUNT,SUM,AVG,MAX,MIN
ex1:求教师工资的总额
Select Sum(Salary) From Teacher;
ex2:求数据库的平均成绩
Select AVG(Score) From Course C,SC Where C.Cname=‘数据库’ and C.C#=SC.C#;
分组查询与分组过滤
分组:SQL可以将检索到的元组按照某一条件进行分类,具有相同条件值得元组划到一组或一个集合中,同时处理多个组或集合的聚集运算。
分组基本语法:
Select 列名[ expr | agfunc(列名) [[,列名 | expr | argfunc(列名)]…] From 表名1[,表名2…]
[Where 检索条件] [Group by 分组条件];
分组条件可以是 列名1,列名2…
expr可以是常量、列名、或由常量、列名、特殊函数及算数运算符构成的算术运算式。特殊函数的使用需要结合各自DBMS的说明书。
ex:求每一门课程的平均成绩
Select C#,AVG(Score) From SC Group by C#;
聚集函数是不允许用于Where子句中的,Where子句是对每一元组进行条件过滤,而不是对集合进行条件过滤。
分组过滤:若要对集合(即分组)进行挑拣过滤,即满足条件的集合/分组留下,不满足条件的集合/分组提出。
Having子句,又称为分组过滤子句。需要有Group by子句支持,换句话,没有Group by子句,遍不能有Having子句。
基本语法:
Select 列名[ expr | agfunc(列名) [[,列名 | expr | argfunc(列名)]…] From 表名1[,表名2…]
[Where 检索条件] [Group by 分组条件 [Having 分组过滤条件]];
ex:求不及格课程超过两门的同学的学号
Select S# From SC Where Score<60 Group by S# Having Count(*)>2;
SQL语言之视图及其应用
对应概念模式的数据在SQL中被称为基本表(Table),而对应外模式的数据称为视图(View)。视图不仅包含外模式,而且包含其E-C映像。
SQL数据库结构
- 基本表是实际存储于存储文件中的表,基本表中的数据是需要存储的。
- 视图在SQL中只存储其由基本表导出视图所需要的公式,即由基本表产生视图的映像信息,其数据并不存储,而是在运行过程中动态产生和维护的。
- 对视图数据的更改最终要反映在基本表的更改上。
视图需要“先定义,再使用”
定义视图:
create view view_name [(列名[,列名]…)] as 子查询 [with check option]