数据库系统原理
第一章 绪论 第一节 数据管理的发展 一、数据管理的目标: 在适当的时候以适当的形式向适当的人提供适当的数据。 第一章 绪论 第一节 数据管理的发展 一、数据管理的目标: 在适当的时候以适当的形式向适当的人提供适当的数据。 为此,必须进行数据的收集、组织、控制、存储、选取、维护。 二、数据管理的内容 1、侧重于组织业务的管理:负责制定并执行整个组织中关于数据的定义、组织、保护与有效使用的政策、过程、实践和计划。 2、侧重于技术的管理:负责实现数据作为一种资源的集中控制管理。
三、数据管理的发展阶段 1、人工管理阶段 2、文件管理阶段 3、数据库系统阶段 四、数据库系统的特点 数据库的概念起源于“共享数据资源,离释数据的个人控制”。其思想是对数据实施统一的、集中的、独立的管理,使得数据的存储独立于使用它的程序。 1、数据的一体化、结构化。 2、数据共享性。 (1)不同的应用可以使用同一数据库。 (2)可以允许不同的应用在同一时刻去存取同一数据。 (3)不仅当前存在的应用可以使用这个数据库,对于未来出现的新应用同样也应当能够使用同一数据库。 (4)提供与多种程序设计语言的接口。
3、较少的数据冗余度。 4、数据的独立性。 5、对数据实行集中统一的控制。 (1)系统提供统一的数据定义、增删,检索以及更新操作的手段 (2)统一控制数据的安全性、完整性和保密性,使得对数据应用更加有效。 五、数据库的新发展 1、分布式数据库 2、逻辑、知识、智能数据库 3、专家数据库 4、多媒体数据库 5、工程数据库 6、面向对象的数据库 7、并行数据库 8、空间数据库 9、XML数据库 10、数据中心
第二节 数据库基本概念 一、数据库系统概念 1、数据库(DB) 2、数据库管理系统(DBMS) 3、数据库应用系统(DBAS) 第二节 数据库基本概念 一、数据库系统概念 1、数据库(DB) 2、数据库管理系统(DBMS) 3、数据库应用系统(DBAS) 4、数据库系统(DBS) 二、数据库系统的组成 1、数据库系统软件 2、数据库系统用户 3、数据库系统硬件
三、数据库管理系统的基本功能 1、数据定义 2、数据管理 3、数据库的建立和维护 4、数据通讯 四、数据库系统的分级模式结构 在一个数据库系统中,有各种类型的人员,他们从不同的角度以各自的观点来看待数据库,从而形成了数据库的分层结构。
1、模式:是数据库中全部数据的一个逻辑表示或描述。它不仅是数据的逻辑结构的定义,而且要定义与数据有关的安全性、完整性要求。 2、子模式:是应用程序员或终端用户所见到的局部数据库逻辑结构(与某一应用有关的数据的逻辑表示)。子模式通常是模式的子集。不同的用户的子模式的描述是不同的。即使对模式中同一数据,在不同的子模式中的结构、类型、长度、保密级等都可以不同。 3、内模式:是全体数据库数据的内部表示,用来定义数据的存储方式和物理结构。 4、子模式/模式的映像:定义了子模式和模式之间的对应关系,通常包含在子模式中。 5、模式/内模式的映像:定义了数据逻辑结构和存储结构之间的对应关系,通常包含在模式描述中。 6、逻辑独立性是指当改变模式时只需改变子模式/模式的映像,应用程序可以不必修改。 7、物理独立性是指当数据库的存储结构改变时,只需改变模式/内模式的映像,模式可以不变。
五、一个DBMS访问数据库中的数据的过程
第三节 数据模型 一、数据模型概念 1、定义:数据库系统中用于提供信息表示和操作手段的形式构架,它包括形式化描述数据、数据之间的联系及有关的语义约束条件。 2、类型: 信息模型(或称概念模型),是独立于任何计算机实现的。这类数据模型完全不涉及信息在计算机系统中的表示问题,只用来描述某个特定的组织所关心的信息结构。 (基本或结构)数据模型,是按计算机系统的观点对数据建模,直接面向数据库中的数据的逻辑结构。
3、三要素: 数据结构------形式化描述数据和数据之间的联系 数据操作------对数据库中各种对象的操作及有关的操作规则 完整性约束------有关的语义约束规则 二、概念模型 1、概念模型是对现实的抽象 。如实体一联系模型(E-R模型)、语义网络模型等 。
2、E-R模型 实体—联系模型是一种概念模型,其基本语义单位是实体与联系。通常用实体—联系图(E-R图)表示实体—联系模型。E-R图的概念包括: 实体 联系 属性 E-R图提供了表示实体型、属性和联系的方法。用矩形表示实体型,椭圆形表示属性,菱形表示联系。实体、联系和属性的名称分别填入图形框内,用无向边连接实体、属性和联系,并在连接实体和联系的无向边旁标明联系的类型。 书中用箭头表示1对多或1对1的联系中的1端。
3、E-R模型实例 实体 实体的属性
联系
联系:也可以用箭头表示类型
也可以用箭头表示类型
4、高级E-R模型 多向联系 多向联系转换到双向联系可以通过将联系变成连接实体(如教学由联系变成实体)的方式实现。
角色 在一个联系中一个实体可以出现多次,表示不同的角色。
实体间的相属关系(子类)
关键字
弱实体集 (组成一个实体集的关键字的属性中的一些或全部属于另一个实体集) 弱实体集的一种:层次关系
弱实体集的另一种:连接实体集
约束 >5
参照完整性
三、基本数据模型 基本数据模型则是对概念模型的转换 。目前使用最为广泛的基本数据模型有网状模型、层次模型和关系模型三种。 1、层次数据模型 层次模型是用树形结构来表示实体与实体之间联系的模型。其中树的结点表示实体,边表示联系。父子结点之间的联系是一对多的。层次模型中的树为有序树,实体之间的联系关系是单向的,树结点中任何结点的任何属性都是不可再分的简单型数据。 2、网状数据模型 网状数据模型用网状结构来表示实体与实体间联系。其中结点表示实体,边表示联系。结点之间的联系可以是一对一、一对多和多对多的。
3、关系数据模型 关系数据模型是三种基本数据中最晚发展但相对建模能力最强的。关系数据模型用二维表格(即集合论中的关系)来表示实体和实体间的联系,保证了对实体和联系的描述的一致性。表中的每一行是一个元组,相当于一个记录。每一列是一个属性值集,列可以命名称为属性名。关系是元组的集合。关系数据模型有严格的数学基础,可直接表达多对多的联系。例如,实体学生可以用表格学生(学号,姓名,专业,班级)表示。联系选修也可以用表格选修(学号,课程名,成绩)表示。
第二章 关系数据库 第一节 关系模型的基本概念 一、笛卡尔积 1、域:同一类值的集合。 第二章 关系数据库 第一节 关系模型的基本概念 一、笛卡尔积 1、域:同一类值的集合。 2、设D1,D2,……,Dn是域,则D1,D2,……,Dn 的笛卡尔积为 D1*D2*。。。。。。*Dn={(d1,d2,……,dn)| diєDi,i=1,2,……,n} 3、笛卡尔积中的每个元素(d1,d2,……,dn)叫做一个n元组,简称元组,元组中每个di叫做一个分量。
二、关系 1、定义:笛卡尔积D1*D2*。。。。。。*Dn的任意一个子集叫做D1,D2,……,Dn上的一个n元关系,简称一个关系。 2、表示: R(D1,D2,……,Dn) n-------关系的目或度 3、性质: 关系是元组的集合。 元组的各分量叫做属性。 每个关系及属性都要命名,属性的取值范围是域。 表中的每一列属性都是不可再分的基本数据项。 各列被指定一个不同的名字。 不允许有完全相同的行。 行、列次序均无关。
第二节 关系数据模型 一、关系模型组成 1、传统的数据模型包括:数据结构、物理存储方法、存取路径、完整性和安全性的约束条件。 第二节 关系数据模型 一、关系模型组成 1、传统的数据模型包括:数据结构、物理存储方法、存取路径、完整性和安全性的约束条件。 2、关系模型定义:表示数据库中每个关系的框架的集合。 3、关系模型包括:数据结构、操作集合、完整性约束条件 二、关系模式 1、定义:对关系的描述,是一个关系的属性名序列。 2、组成:关系名,属性名,属性向域的映像,属性间数据的依赖关系。
三、关系操作 1、特点: 一次操作可存取多个元组。 语言的非过程化。 将数据操作、数据定义和数据控制等功能成功地集成到一个语言中 2、关系数据操作语言可分为两类 关系代数------直接引用关系的运算来达到操作目的。 关系演算------将谓词演算引入关系运算之中,分为元组关系演算和域关系演算两种
四、关系的完整性 1、实体完整性 2、参照完整性 3、用户定义的完整性 五、视图 1、概念:反映局部逻辑结构,系统中仅存放其定义,实际数据并不依赖于视图而是依赖于数据模式来存放在数据库中。是一个虚关系集。 2、在关系数据库中,视图通常由关系数据库模式的某个关系中满足用户给定条件的若干属性列或元组组成,也可以是对若干个不同关系进行关系运算的结果。
六、关系数据模型的特点: 1、对用户提供统一的单一数据结构形式。 2、关系模型的逻辑数据库结构和相应的操作完全独立于数据的存储方式,确保了高度的数据独立性。 3、数据库的操作都可归结为关系的运算,使数据库的理论建立在坚实的数学基础上。 4、关系数据语言与一阶谓词逻辑的内在联系,为以关系数据库为基础的推理系统和知识库的研究提供了方便。 5、简化数据管理人员的工作,易于对数据库进行重组和控制。 6、便于向分布式方向发展。 7、运行效率不够高。 8、建模能力较弱,不适于管理复杂对象。
第三节 关系数据库系统的数据操作 一、关系数据语言 1、特点: 灵活方便,表达能力和功能都很强 一般是非过程化语言 第三节 关系数据库系统的数据操作 一、关系数据语言 1、特点: 灵活方便,表达能力和功能都很强 一般是非过程化语言 可以作为查询语言单独使用,也可以嵌入主语言中使用 是面向集合的语言 2、关系数据语言的核心部分是查询 3、几种关系数据语言 ISBL 纯关系代数语言 QUEL 基于元组演算的查询语言 SQL 类似于元组演算的语言 QBE 基于域关系演算的语言
二、关系代数 1、概念:直接应用关系的运算来表达操作目的。 2、关系代数运算包括: (1)传统的集合运算:并、差、交、笛卡尔积 (2)专门的关系运算:选择、投影、连接、除 3、例: 两个关系R和G若具有相同的目,且相应的属性值取自同一个域,则称这两个关系是并相容的。 R A B C G A B C ---------------------- ---------------------- a1 b1 c1 a1 b2 c2 a1 b2 c1 a1 b1 c1 a2 b1 c2 ------------------------- a2 b2 c3 ------------------------------------
-------------------------------------------- RUG= A B C 并 ------------------------------------------- a1 b1 c1 a1 b2 c2 a1 b2 c1 a2 b1 c2 a2 b2 c3 -------------------------------------------- R G= A B C 交
-------------------------------------------- R-G= A B C 差 ------------------------------------------- a1 b2 c1 a2 b1 c2 a2 b2 c3 --------------------------------------------
σc=‘c1’( R ) = A B C 选择 ПB R=R[B] B 投影 ------------------------ ---------------------------------------- ПB R=R[B] B 投影 b1 b2 ------------------------------------
R A B C G C D ---------------------- ---------------- a1 b1 5 5 d2 a1 b2 3 4 d1 a2 b1 5 ----------------- a2 b2 9 ------------------------------------
--------------------------------------------- a1 b1 5 5 d2 R*G= A B R .C G.C D --------------------------------------------- a1 b1 5 5 d2 a1 b1 5 4 d1 a1 b2 3 5 d2 a1 b2 3 4 d1 a2 b1 5 5 d2 a2 b1 5 4 d1 a2 b2 9 5 d2 a2 b2 9 4 d1 --------------------------------------------------- 广义笛卡尔积
R*G = A B R .C G.C D R*G = A B R .C G.C D 联接 a1 b2 3 5 d2 a1 b2 3 4 d1 --------------------------------------------------- R*G = A B R .C G.C D R .C=G.C --------------------------------------------- 等值联接 a1 b1 5 5 d2 a2 b1 5 5 d2
R |╳| G= A B C D 自然联接 --------------------------------------------- 自然联接 --------------------------------------------- a1 b1 5 d2 a2 b1 5 d2 --------------------------------------------------- 例: branch (branch-name, branch-city, assets) customer (customer-name, customer-street, customer-only) account (account-number, branch-name, balance) loan (loan-number, branch-name, amount) depositor (customer-name, account-number) borrower (customer-name, loan-number)
loan-number (amount > 1200 (loan)) 既有存款又有贷款的顾客的姓名 贷款额高于1200元的贷款 amount > 1200 (loan) 贷款额高于1200元的贷款的贷款号 loan-number (amount > 1200 (loan)) 既有存款又有贷款的顾客的姓名 customer-name (borrower) customer-name (depositor) 在Perryridge支行贷款的顾客姓名 1、customer-name (branch-name=“Perryridge” (borrower.loan-number = loan.loan-number(borrower x loan))) 2、customer-name(loan.loan-number = borrower.loan-number( (branch-name = “Perryridge”(loan)) x borrower))
三、关系演算 1、元组关系演算 (1)概念:面向元组的演算对象是元组,即对于任一给定关系,元组变量的所有获得值都是该关系中的元组。 (2)表示: { t | φ( t ) }---------表示使φ为真的元组集合 t------元组变量 φ( t ) ------公式,由原子公式和运算符组成 (3)原子公式 R ( t )------表示断言“ t 是 R 中的一个元组” t [ i ] θ u [ j ] ------表示断言“ t 的第 i 个分量和 u 的第 j 个分量满足比较关系 θ ” t [ i ] θ c 或 c θ t [ i ] ------表示断言“ t 的第 I 个分量和常数 c 之间满足θ关系”
-------------- ---------------- a1 b1 c1 a1 b2 c2 a1 b2 c1 a1 b1 c1 (4)公式:由原子公式和运算符经过有限次运算而形成的。 (5)运算符及优先级 算术比较运算符 高 存在量词和全称量词 | ¬ | 逻辑运算符{ ٨ | ٧ 低 R A B C G A B C -------------- ---------------- a1 b1 c1 a1 b2 c2 a1 b2 c1 a1 b1 c1 a2 b1 c2 --------------- a2 b2 c3 ----------------
---------------------- S={t | R(t) ^G(t)}= A B C ---------------- a1 b1 c1 ------------------ = R G S={t | R(t) ∨ G(t)}= A B C ---------------------- a1 b1 c1 a1 b2 c2 a1 b2 c1 a2 b1 c2 a2 b2 c3 ---------------------- = R U G
S={ t| R(t) ^ t[2]=‘b2’} = A B C --------------- a1 b2 c1 a2 b2 c3 ---------------- = σ B=‘b2’ ( R )
元组关系演算与关系代数的等价性 投影 ∏A( R ) = { t | sR ( s[A] = t[A] ) } 选择 F(A)(R) = { t | tR F(t[A]) } 广义笛卡儿积 R(A) S(B) = { t | uRsS( t[A] = u[A] t[B] = s[B])} 并 RS={ t | tR tS} 差 RS={ t | tR ┑tS}
(6)QUEL------一个基于元组关系演算的语言 ①功能:检索、更新、权限、完整性、视图 ②语句: 数据定义:基本关系定义、元组变量定义、视图定义、索引定义 数据检索 数据更新:数据插入、数据删除、数据修改、撤销关系等
range of u1 is R1 …… range of uk is Rk retrive ( ui. A1, ……, uir. Ar) ③QUEL查询的通常形式 range of u1 is R1 …… range of uk is Rk retrive ( ui. A1, ……, uir. Ar) where φ (u1, ……, uk) 其中,ui Є Ri, Ai 为属性名。 可写成: range of 变量名 is 关系名 retrive ( 目标表 ) where 条件表达式
2、域关系演算 (1)概念:在演算中不用元组变量而用域变量,它表示元组的分量。 (2)原子公式 R ( X1, X2, ……, XK )------由分量( X1, X2, ……, XK )组成的元组Є R Xiθc 或 c θXi------Xi 与 c 之间满足关系θ Xiθyi------ Xi 与 yi 之间满足关系θ (3)域关系演算表达式 {X1, X2, ……, XK| φ ( X1, X2, ……, XK ) } 表示所有使 φ 为真的那些 X1, X2, ……, XK所组成的元组的集合 (4)QBE------一种域演算语言 特点: 查询结果和查询要求用表格给出 二维语法 用户性能好
-------------- ---------------- a1 b1 c1 a1 b2 c2 a1 b2 c1 a1 b1 c1 R A B C G A B C -------------- ---------------- a1 b1 c1 a1 b2 c2 a1 b2 c1 a1 b1 c1 a2 b1 c2 --------------- a2 b2 c3 ---------------- S={xyz| R(xyz)^ G(xyz) } = A B C a1 b1 c1 ------------------ S( x,y,z) - R(x,y,z) AND G(x,y,z)
查找贷款数高于700的贷款的号码 查找所有与jones住在同一城市的顾客的姓名
查找所有在Perryridge支行又贷款的顾客的姓名
查找Perryridge支行所有户头的顾客名、帐户号和帐户金额。 Access QBE的例子 查找Perryridge支行所有户头的顾客名、帐户号和帐户金额。
查找有多个银行帐户户头的顾客的姓名、所在街道和城市
第五节 关系运算的安全限制和三种运算的等价性 第五节 关系运算的安全限制和三种运算的等价性 一、关系代数和关系演算的等价表示 二、概念 1、无限关系: 关系{ t | ¬R ( t ) }表示所有不在 R 中的元组的集合,在这种情况下为了判定一个命题的真假可能需要无穷次验证,这种关系为无限关系。 2、安全运算:不产生无限关系和无穷次验证的运算 3、安全表达式:安全运算的表达式
三、安全限制: 1、定义:为了保证运算为安全运算所加的限制。 2、关系代数是安全运算 关系演算不是安全运算 3、在进行了安全限制后,三种关系运算的表达能力是等价的,它们之间可以相互转化。 4、办法:定义一个有限的符号集 DOM ( φ ) , 使 φ 中出现的及中间结果和最后结果的关系中的所有符号属于 DOM ( φ )。
第三章 关系数据库标准语言—SQL 第一节 概述 一、历史和特点 二、基本概念: 第一节 概述 一、历史和特点 二、基本概念: SQL是Structured Query Language(结构化查询语言)的缩写,它是目前使用最广泛的数据库语言,SQL是由IBM发展起来的,后来被许多数据库软件公司接受而成为了业内的一个标准。 SQL作为一个ANSI标准,一直在不断改进,现在最新的标准是SQL99。 支持关系数据库三级模式结构 包括数据定义、数据操纵和数据控制功能
三、语句: 按功能可分为数据定义子语言(DDL)、数据操纵子语言(DML)、数据控制子语言(DCL)
第二节 SQL的数据定义 一、数据定义组成 1、基本关系定义及变更 2、视图定义 3、索引定义 二、关系的定义及变更 1、关系定义: (1)语法: CREATE TABLE 关系名(属性表); (2)属性表 属性名 属性类型 {,属性名 属性类型}
Sql server 数据类型 A 二进制数据 字符型数据 Unicode数据 位数据类型 binary[(n)]:存放n字节固定长度二进制数据,1<=n<=8000 varbinary[(n)]:存放n字节可变长度二进制数据,1<=n<=8000 image:存放最大长度为2^31-1的二进制数据 字符型数据 char[(n)]:存放固定长度的n个字符数据,1<=n<=8000 varchar[(n)]:存放可变长度的n个字符数据,1<=n<=8000 text:存放最大长度为2^31-1的字符数据 Unicode数据 nchar[(n)]:存放固定长度的n个Unicode数据,1<=n<=4000 nvarchar[(n)]:存放可变长度的n个Unicode数据,1<=n<=4000 ntext:存放最大长度为2^30-1的Unicode数据 位数据类型 bit:只有两种取值:0和1。在输入0以外的其他值时,系统均把它们当作1看待,该类型常作为逻辑变量使用,表示真、假、是、否等。 A
日期和时间数据 数字型数据 货币数据 datetime:存放从1/1/1753到12/31/9999的时间数据,精确到1/1000秒。 smalldatetime:存放从1/1/1990到6/6/2079的时间数据,精确到分。 数字型数据 bigint:存放从-2^63到2^63的整型数据。 int:存放从-2^31到2^31的整型数据。 smallint:存放从-2^15到2^15的整型数据。 tinyint:存放从0到255的整型数据。 decimal[(p[,s])]、numeric[(p[,s])]:固定精度的小数,当取最大精度时范围从-10^38-1到10^38-1,p为精度(1<=P<=38),s为小数点后位数(0<=s<=p)。 float[(n)]:存放从-1.79E+38到1.79E+38的浮点数,n为精度(1<=n<=53)。 real:存放从-3.40E+38到3.40E+38的浮点数。 货币数据 money:存放从-2^63到2^63-1的货币数据,精度为货币单位的10/1000。 smallmoney:存放从-214,748.3648到214,748.3647的货币数据,精度为货币单位的10/1000。
文本和图像数据 文本和图像数据用text、ntext、image数据类型来表示,由于数据量大,一般存储在专门的页中,在数据行的相应位置处只记录指向这些数据实际存储位置的指针。SQL Server 2000提供了将小型文本和图像数据在行中存储的功能。 格式1:sp_tableoption ‘表名’,‘text in row’,’ON’ 功能:设置在指定表的行中存储文本和图像数据。 格式2:sp_tableoption ‘表名’,‘text in row’,’1000’ 功能:设置不大于1000字节的文本和图像数据直接在行中存储。 格式3: sp_tableoption ‘表名’,‘text in row’,’OFF’ 功能:设置不在指定表的行中存储文本和图像数据。 说明:1.文本和图像数据的大小不超过指定的上限值(上限值在24字节~7000字节之间,默认为256字节)。 2.数据行有足够的空间存放这些数据。
IDENTITY列 即标识列,由系统自动生成能够标识表中每一行数据的唯一序列值。 格式:IDENTITY [(SEED,INCREMENT)] 功能:定义标识列。 SEED:初始值。 INCREMENT:增值。 说明:1.每张表只允许有一个IDENTITY列。 2.该列必须使用下列数据类型之一:decimal、int、numeric、smallint、tinyint。 3.该列不允许有空值,且不能有默认值。
CREATE TABLE STUDENT ( SNO VARCHAR(6), SNAME VARCHAR(20), SEX CHAR(2) , SROOM VARCHAR(10) ) ; CREATE TABLE COURSE CNO VARCHAR(8), CNAME VARCHAR(30), CROOM VARCHAR(20) );
CREATE TABLE SC ( SNO VARCHAR(6), CNO VARCHAR(8), SCORE DECIMAL(3, 0), TEACHER VARCHAR(20) );
2、关系撤销 语法: DROP TABLE 关系名; 例:DROP TABLE STUDENT; 3、关系修改 ADD (属性表); 语法:ALTER TABLE 关系名 MODIFY (属性表); 例:在STUDENT中将SNO的最大字段长度改为8。 ALTER TABLE STUDENT MODIFY (SNO VARCHAR2(8)); 增加一出生年月属性 ADD (BIRTHDAY DATE);
三、视图定义 1、语法: CREATE VIEW 视图名 AS SELECT 子句 2、从单一关系中导出视图 例: CREATE VIEW SVIEW AS SELECT SNO,SNAME FROM STUDENT WHERE SEX=‘ 女’ ;
3、从多个关系中导出视图 CREATE VIEW CVIEW AS SELECT CNO FROM SC WHERE SNO IN (SELECT SNO FROM STUDENT WHERE SROOM=‘南二舍201室’); 4、使用视图 例: SELECT * FROM CVIEW; 5、视图撤销 语法:DROP VIEW 视图名; 例: DROP VIEW CVIEW;
四、索引 1、索引定义 CREATE [ UNIQUE ] INDEX 索引名 ON 关系名( 属性名 ASC {,属性名 ASC } ); DESC DESC 例:CREATE INDEX XSC ON SC ( CNO ) ; 2、索引删除 DROP INDEX 索引名; 例: DROP INDEX XSC;
列定义了一个经常被用来连接另一张基表的外键 是的,因为列被用在连接中 列定义了一个通过关联完整性实现的外键 是的,用来提高有效操作的性能 3、创建索引的一般性原则 情况 是否创建索引 列定义了一个唯一主键 是的,索引将实现唯一性 列定义了一个主键并用在查询的连接条件中 是的,用来减少在连接中所读的纪录 列定义了一个主键并且基表存放不到250条记录 否,除非列被用在基表连接中 列定义了一个经常被用来连接另一张基表的外键 是的,因为列被用在连接中 列定义了一个通过关联完整性实现的外键 是的,用来提高有效操作的性能 列经常被用在一个返回不到百分之五的行的查询的WHERE子句中 是的,只有不到百分之五的行被返回
五、存储过程 1、存储过程目的 可以完成既定的功能,而不需要写一长串的代码, 安全性高、减少网络流量、提高代码的重用性,减少预编译时间、执行速度快。 2、语法: ORACLE: 创建过程: create procedure 过程名(参数) as 变量 begin 过程体 end 过程名; 修改过程只需将上面的create改为replace。 删除过程 drop procedure 过程名;
SQL SERVER 流控制语句 WAITFOR BEGIN…END GOTO IF…ELSE CASE WHILE RETURN PRINT BEGIN…END IF…ELSE WHILE BREAK CONTINUE
一般格式 CREATE PROC[EDURE] 存储过程名 [@参数名 数据类型 [=DEFAULT][OUTPUT]] [,…n] [WITH {RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}][FOR REPLICATION] AS T-SQL语句[,…n] 各参数意义
各参数意义 参数名:存储过程中的输入、输出参数。 数据类型:参数的数据类型。 DEFAULT:参数指定的默认值。 OUTPUT:输出参数。 RECOMPILE:执行完存储过程后,不在高速缓存里保留存储过程备份。 ENCRYPTION:对存储过程信息加密。 FOR REPLICATION:为复制创建的存储过程不能在订购服务器上执行,只有在创建过滤存储过程时(仅当进行数据复制时过滤存储过程才被执行),才使用该选项。FOR REPLICATION与WITH RECOMPILE 选项是互不兼容的。
3、实例: ORACLE 创建一个过程,可根据参数执行修改表中数据的工作。并返回执行结果。 输入参数: TABLENAME 更新时操作的表名; SQLSTRING 更新时所用的SQL语句; CONSTRING 更新时所用的条件语句,若没有条件则用“NULL” 输出参数: 调用成功返回 "T", 调用失败返回错误信息
create or replace procedure updatedata ( tablename IN VARCHAR, sqlstring IN VARCHAR, constring IN VARCHAR, '条件语句 execresult OUT VARCHAR ) AS tstr VARCHAR (500); BEGIN IF (sqlstring IS NULL) THEN execresult := 'F'; ELSE IF (constring IS NULL) THEN tstr := 'update ' || tablename || ' set ' || sqlstring; ELSE tstr :='update '|| tablename || ' set ' || sqlstring || ' where ' || constring; END IF; EXECUTE IMMEDIATE tstr; COMMIT; execresult := 'T'; END IF; EXCEPTION WHEN OTHERS THEN ROLLBACK; execresult := 'F' || SQLCODE; END updatedata;
SQL SERVER 建立一个按照输入值查找符合要求的职工名单的存储过程 创建存储过程: CREATE PROC CCGC3 @XM VARCHAR(8) AS SELECT '职工名单'=姓名 FROM ZYL1 WHERE 姓名 LIKE @XM 调用存储过程: CCGC3 '王%'
六、触发器 1、定义: 当事件发生时检查条件决定是否执行动作。 2、语法: ORACLE: CREATE TRIGGER 触发器名 <AFTER/ BEFORE><UPDATE/ INSERT/ DELETE> OF 属性名 ON 关系名 WHEN 子句 [<FOR EACH ROW>]; BEGIN 触发器体; END;
SQL SERVER: CREATE TRIGGER 触发器名 ON {表名|视图名}{FOR|AFTER|INSTEAD OF} [INSERT,UPDATE,DELETE] AS SQL语句
3、实例 ORACLE: CREATE TABLE OPERATOR_INFO ( USER_ID VARCHAR(20), USER_NAME VARCHAR(40), OPERATOR_CODE VARCHAR(30) );
CREATE TABLE COUNTRY_INFO ( COUNTRY_CODE VARCHAR(4) PRIMARY KEY, COUNTRY_NAME VARCHAR(32) , COUNTRY_ENGNAME VARCHAR(32), LOGIN_DATE DATE, LAST_DATE DATE DEFAULT SYSDATE, OPERATOR_CODE VARCHAR(30) REFERENCES OPERATOR_INFO(OPERATOR_CODE) );
BEFORE INSERT OR UPDATE ON COUNTRY_INFO FOR EACH ROW BEGIN CREATE OR REPLACE TRIGGER CHANGE_COUNTRY BEFORE INSERT OR UPDATE ON COUNTRY_INFO FOR EACH ROW BEGIN IF INSERTING THEN :NEW.LOGIN_DATE:=SYSDATE; END IF; :NEW.LAST_DATE:=SYSDATE; :NEW.OPERATOR_CODE:=USER; END CHANGE_COUNTRY;
SQL SERVER 创建一个触发器 create trigger cfq1 on zyl1 for update as select * from zyl1 Return 触发触发器 update zyl1 set 职称='工程师' WHERE 编号='10'
4、触发器规则和防止非法修改 (1)只有数据表的属主可以创建或者删除数据表上的触发器。 (2)不同于视图和存储过程,在触发器内部许可权限应用的方式是一样的,就同通常情况下的SELECT语句行为类似。这样,如果某位用户无权更新table_b而他又更新了table_a并触发了trigger_a去试图更新table_b,那么触发器将失败而且修改也不可进行。 (3)在一个触发器里你可以引用最多192个其他数据库对象,比如表、视图等等。 (4)不允许任何形式的Create和Drop命令。然而,临时表可以被触发器所调用的存储过程调用。 (5)不允许修改表/数据库。 Grant和Revoke都被禁用。
5、数据库触发器有以下的作用: (1)安全性: 可以基于时间限制用户的操作,例如不允许下班后和节假日修改数据库数据。 可以基于数据库中的数据限制用户的操作,例如不允许股票的价格的升幅一次超过10%。 (2)审计。可以跟踪用户对数据库的操作。 审计用户操作数据库的语句。 把用户对数据库的更新写入审计表。 (3)实现复杂的数据完整性规则。 实现非标准的数据完整性检查和约束。触发器可产生比规则更为复杂的限制。与规则不同,触发器可以引用列或数据库对象。例如,触发器可回退任何企图吃进超过自己保证金的期货。 提供可变的缺省值。
(4)实现复杂的非标准的数据库相关完整性规则。触发器可以对数据库中相关的表进行连环更新。 在修改或删除时级联修改或删除其它表中的与之匹配的行。 在修改或删除时把其它表中的与之匹配的行设成NULL值。 在修改或删除时把其它表中的与之匹配的行级联设成缺省值。 触发器能够拒绝或回退那些破坏相关完整性的变化,取消试图进行数据更新的事务。当插入一个与其主健不匹配的外部键时,这种触发器会起作用。例如,可以在books.author_code列上生成一个插入触发器,如果新值与auths.author_code列中的某值不匹配时,插入被回退。 同步实时地复制表中的数据。 自动计算数据值,如果数据的值达到了一定的要求,则进行特定的处理。例如,如果公司的帐号上的资金低于5万元则立即给财务人员发送警告数据。
第三节 SQL的数据操作功能 一、数据检索 1、语法: SELECT 属性名表或库函数 FROM 基本表 ( 或视图 ) [ WHERE 条件表达式 ] [ GROUP BY 属性名 [ HAVING 库函数表达式 ]] [ ORDER BY 属性名 ASC ] DESC
2、例: (1)找出所有学生的姓名 SELECT SNAME FROM STUDENT ; (2)找出所有课程的信息 SELECT * FROM COURSE ; (3) 查找课程号为03的课程中不及格的学生学号 SELECT SNO FROM SC WHERE (CNO= '03') AND (SCORE<60);
(4)显示所有女生的信息,要求照姓名,学号,宿舍排列 Select sname, sno, sroom From student Where sex= '女' ; (5) 去掉重复的结果: 显示所有学生的姓名,要求去掉重名的姓名。 Select distinct sname From student; (6) 别名 别名是一个SQL功能,允许你在一个查询中为表格或字段创建一个符号,可以在处理自连接时很方便地使用。 一个别名通用的格式是 表名.字段名 AS 别名 或: 表名 AS 别名
例:找出学生中同名学生 显示所有学生的姓名,要求显示中将sname 改为name. Select sname as name From student; (7)别名的使用: 例:找出学生中同名学生 SELECT DISTINCT A.SNAME FROM STUDENT AS A, STUDENT AS B WHERE A.SNAME=B.SNAME AND A.SNO<>B.SNO;
查询选修了课程号为2的课程的同学选修了哪些课。 Select b.cno From sc as a, sc as b Where a.cno='2' and a.sno=b.sno; (8) 显示字段值改变后的数据. 查询将选修了课程号为“2”的课程的所有学生的成绩提高10%后的新成绩。 在显示中将属性名改为new score. Select score*1.1 as new_score From sc Where cno=‘2’;
(9) 字符函数: 查找住在南边宿舍的学生的学号和姓名 Select sno, sname From student Where left(sroom,2)= '南'; (10)between的使用: 查找成绩位于60分到80分的学生的学号 Select sno From sc Where score between 60 and 80; 或者 Where score>=60 and score<=80;
WHERE SNO IN (SELECT SNO FROM SC WHERE CNO IN ( SELECT CNO FROM COURSE (11)子查询: 查找选修了C++的学生姓名 SELECT SNAME FROM STUDENT WHERE SNO IN (SELECT SNO FROM SC WHERE CNO IN ( SELECT CNO FROM COURSE WHERE CNAME= 'C++')); 等价于: Select sname From student,sc,course Where student.sno=sc.sno and course.cno=sc.cno and course.cname=‘c++’;
思考:为什么后一个IN可以用=替代而前一个IN不可以? 或: SELECT SNAME FROM STUDENT WHERE SNO IN ( SELECT SNO FROM SC WHERE CNO = ( SELECT CNO FROM COURSE WHERE CNAME=‘C++’)); 思考:为什么后一个IN可以用=替代而前一个IN不可以?
或: EXIST后面的条件为真或假。 SELECT SNAME FROM STUDENT WHERE EXISTS (SELECT * FROM SC WHERE SNO=STUDENT.SNO AND CNO IN ( SELECT CNO FROM COURSE WHERE CNAME=‘C++’)); EXIST后面的条件为真或假。
(12) 多个条件: 查找选修了DBMS或 OS或 OR的学生的学号。 Select sno From sc Where cno in ( select cno from course where cname= 'DBMS' OR cname= 'OS' or cname= 'OR'); 或者 where cname in ('DBMS', 'OS', 'OR'));
(13) not的使用: 查找没有选修DBMS或 OS或 OR的学生的学号。 select sno from student where sno not in(Select sno From sc Where cno in ( select cno from course where cname in ('db ', 'os ', 'or '))); 或者 where cname ='db ‘ or cname='os ‘ or cname='or '));
(14) Null 的使用 查找所有选修了课程但没有成绩的学号 Select sno From sc Where score is null;
WHERE SNAME LIKE ‘章_ _’; (16) 在匹配字符中有_或%的查找方法 SELECT * FROM COURSE SELECT SNAME FROM STUDENT WHERE SNAME LIKE '章% '; WHERE SNAME LIKE ‘章_ _’; (16) 在匹配字符中有_或%的查找方法 SELECT * FROM COURSE WHERE cname like ' os\_linux ' escape ' \ ';
(17) 建立新表 SELECT * INTO 新表 FROM 原表 例:SELECT 姓名 INTO WOMENSTU FROM STUDENT WHERE SEX=‘女’;
where not exists ( select * from sc where student.sno=sc.sno); (18) SQL的存在量词-------EXISTS 显示没有选修课程的学生的基本情况 select * from student where not exists ( select * from sc where student.sno=sc.sno);
(19) 连接查询 可以在select的from子句中使用join来实现多个表之间的关联查询。join也可以使用在任何可以使用关系的地方。 语法 连接类型 + 连接条件 inner join natural left outer join on <谓词> right outer join using (A1,A2,……,An) full outer join 内连接(普通的Θ连接)需要连接条件,如果省略连接条件,将产生笛卡尔积。 using只连接两个关系的指定的公共属性A1,A2,……,An。
例:查询张山所学课程的成绩 select score from sc where sc.sno in (select sno from student where sname= ‘张山’); 或: select score from sc,student where sc.sno=student.sno and student.sname=‘张山’;
select score from sc inner join student on sc.sno=student.sno and student.sname=‘张山’; ------内连接
外连接处理当左右关系中的某个元组与另一个关系中的任一元组在连接属性上都不匹配时,将其其他属性置为空后放入结果集。 外连接运算符+就像是为其所指定的表或视图增加一条“万能”的记录,这条记录有空值组成,它可以和需返回全部记录的表或视图中所有不能与其它记录连接的记录进行连接。由于这个“万能”记录的各属性列全部是空值,同样在连接结果表中也是空值,从而借助空值返回了两个连接表的其中一个表或视图的全部记录。 外连接符+出现在连接运算符的右边时称为右外连接,相应地,如果外连接符+出现在连接运算符的左边则称为左外连接。
例:列出所有学生的姓名和他们所选的课程号(无论是否选修了课程) select sname,cno from sc right outer join student on sc.sno=student.sno; 相当于 from sc,student on sc.sno (+)= student.sno;( ORACLE) 或: select sname,cno on student.sno = (*) sc.sno (SQL SERVER)
3、SQL的常用库函数 COUNT 计数 MAX 求最大值 MIN 求最小值 AVG 计算平均值 SUM 求和
(1) 找出学生选修多于10人的课程号 SELECT CNO FROM SC GROUP BY CNO HAVING COUNT(*)>10; 找出重名的学生 SELECT SNAME FROM STUDENT GROUP BY SNAME HAVING COUNT(*)>1;
(2) 统计各课的平均成绩 SELECT CNO, AVG(SCORE) as average_score FROM SC GROUP BY CNO; (3) 显示各课的最低成绩 SELECT CNO, min(SCORE) as min_score
(4)找出平均成绩在80分以上的课程 Select cno, avg(score) From sc Group by cno having avg(score)>80; 4、any, all 显示所有有成绩比课程号为2的课程学生最好成绩好的课程 Select cno Where score> all (select score from sc where cno= '2 ');
或者 Select cno From sc Where score> (select max(score) from sc where cno= '2'); (2)显示所有有学生的成绩比课程号为2的课程的某个学生成绩好的课程 Where score> any (select score where cno= '2 ');
(3)找出所有成绩都比课程2的所有成绩高的课程 Select cno From sc group by cno having min(score)> all (select score from sc where cno= '2 '); 或者 select cno from course where cno not in (select cno where score<=any(select score where cno= '2 '));
4、SQL与关系代数的对应关系 (1)RUG SELECT * FROM R UNION SELECT * FROM G;
(2)R-G SELECT * FROM R WHERE NOT EXIST ( SELECT * FROM G); (3)R*G SELECT * FROM R, G (4)ƠF(R) SELECT * WHERE F; (5)∏A1,A2,……,AK( R) SELECT A1,A2,…….,AK
二、数据插入 1、语法: INSERT INTO 关系名(属性名表) VALUES (属性值表); 2、例: (1)向STUDENT中插入一条记录。 INSERT INTO STUDENT(SNO,SNAME) VALUES (‘900102’,’汪洋’ ); (2)另建一个基表GRADUATE。 CREATE TABLE GRADUATE ( GNO VARCHAR(6) PRIMARY KEY, GNAME VARCHAR(20) NOT NULL, GBIRTHDAY DATE, GROOM VARCHAR(10) ) ;
将表GRADUATE中的所有记录插入到表STUDENT中。 INSERT INTO STUDENT(SNO, SNAME, SROOM) SELECT GNO, GNAME, GROOM FROM GRADUATE; 源列和目标列的数据类型必须相符。 (3)日期常数的插入------可以利用函数TO_DATE INSERT INTO GRADUATE VALUES(‘200201’, ‘张山’, TO_DATE(’10/01/79’, ‘MM/DD/YY’ ), ‘西一舍201室’);
Sql server 中 set dateformat ymd 则 insert into mytable values(‘2000-12-26’) insert into mytable values(‘2000/12/26’) insert into mytable values(‘2000.12.26’) insert into mytable values(‘2000 12 26’) 都是对的 但这样是错的(日在中间) insert into mytable values('2000-26-12') 要是这样设置就可以了 set dateformat ydm insert into mytable values('2000-26-12') insert into mytable values('2000/26/12') insert into mytable values('2000.26.12') insert into mytable values('2000 26 12')
三、数据删除 1、语法: DELETE FROM 关系名 [ WHERE 条件表达式]; 2、例:DELETE FROM COURSE WHERE CNAME=‘C++’; 四、数据修改: 1、语法: UPDATE 关系名 SET 属性名=属性名改变值 [WHERE 条件表达式]; 2、例: (1)将课程号为’03’的所有成绩提高10%。 UPDATE SC SET SCORE=SCORE*1.1 WHERE CNO=’03’;
一个视图如果连接了多个表,使用了DISTINCT运算符,或者包含了GROUP BY 子句或组函数,该视图是不可被修改的。 (2)将所有女生的成绩提高10%。 UPDATE SC SET SCORE=SCORE*1.1 WHERE SNO IN (SELECT SNO FROM STUDENT WHERE SEX=‘女’); 五、视图的更新 一个视图如果连接了多个表,使用了DISTINCT运算符,或者包含了GROUP BY 子句或组函数,该视图是不可被修改的。 六、sql漏洞 程序员在用sql语句进行用户密码验证时一般是通过一个类似这样的语句来实现的: Sql="Select * from 用户表 where 姓名='"+name+"' and 密码='"+password+"'“
Sql="Select * from 用户表 where 姓名=' jack' and 密码=' ' or 'a'='a"' 当我们在姓名中输入下面的字符串时:jack, 然后输入密码:’or 'a'='a 。变量代换后,sql语句就变成了下面的字符串: Sql="Select * from 用户表 where 姓名=' jack' and 密码=' ' or 'a'='a"' select语句在判断查询条件时,遇到或(or)操作成立就会忽略下面的或操作,而在上面的语句中’a’=‘a’的值永远为true,这意味着无论在密码中输入什么值,均能通过上述的密码验证!
七、练习: 问题:找到os课程的最低成绩和对应的学生姓名。 select sname,score from student,sc,course where score= (select min(score) from sc where cno = (select cno from course where cname = 'os')) and student.sno=sc.sno and cname='os' and sc.cno=course.cno;
select sname, result1 as min_score from student,( select sno,result1 from sc,( select min(score) as result1,cno from sc group by cno having cno in ( select cno from course where cname = 'os' )) as result2 where result2.cno=sc.cno and sc.score=result2.result1) as result3 where result3.sno=student.sno;
第四节 嵌入式SQL 一、一般形式 1、格式: 以C和PL/1作为主语言的嵌入式SQL语句的一般格式为: EXEC SQL <SQL语句> ;
2、通信: 程序中会含有两种不同结构的编程语句,一种是描述性的面向集合的非过程性SQL语句,另一种是过程性的高级语言语句,两者之间必然需要传递数据与状态信息。一般通信的内容包括: ① 主语言向SQL语句提供参数; ② 将SQL语句查询数据库的结果提交给主语言作进一步处理。 其中,主语言向SQL语句提供参数主要用主变量(Host Variable)实现;将SQL语句查询数据库的结果提交给主语言主要用主变量和游标(Cursor)实现。
3、SQL通信区(SQLCA ,SQL Communication Area) ①向主语言传递SQL语句的执行状态信息,反馈给应用程序系统当前工作状态和运行环境信息(这些信息将送到SQL通信区SQLCA中) ② 主语言从SQLCA中取出这些状态信息,能够据此决定接下来执行的语句 ③SQLCA中有一个存放每次执行SQL语句后返回代码的变量SQLCODE。如果SQLCODE等于预定义的常量SUCCESS,则表示SQL语句成功,否则表示出错。应用程序每执行完一条SQL 语句之后都应该测试一下SQLCODE的值,以了解该SQL语句执行情况并做相应处理
4、主变量: 在SQL语句中使用的主语言程序变量简称为主变量。使用所有的主变量时,必须在SQL语句BEGIN DECLARE SECTION与 END DECLARE SECTION之间进行说明。说明之后,主变量可以在SQL语句中任何一个能够使用表达式的地方出现,为了与数据库对象(表名、视图名、列名等)区别,SQL语句中的主变量前要加冒号(:)作为标记。而在SQL语句之外,主变量可直接引用,不必加冒号。
5、游标: 游标是系统为用户开设的一个数据缓存区,存放SQL语句的执行结果,每个游标区都有一个名字。用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言作进一步处理。在具体使用中,游标要先定义,然后打开,再使用,使用完后还要关闭。 (1)定义游标的语法格式为: EXEC SQL DECLARE <游标名> CURSOR FOR <子查询> [;|END-EXEC] (2)打开游标的语法格式为: EXEC SQL OPEN <游标名> [;|END-EXEC] (3)游标取数的语法格式为: EXEC SQL FETCH <游标名> INTO <主变量> [{,<主变量>}] [;|END-EXEC] (4)关闭游标的语法格式为: EXEC SQL CLOSE <游标名> [;|END-EXEC]
6、例:用C语言编程打印SC表的内 容(学号,课程号,得分)。 … EXEC SQL INCLUDE SQLCA; //定义通信区 EXEC SQL BEGIN DECLARE SECTION; char sno(5); char cno(3); int score; EXEC SQL END DECLARE SECTION; //变量说明区 main() { EXEC SQL DECLARE C1 CURSOR FOR SELECT sno, cno, score FROM sc; //定义游标 EXEC SQL OPEN C1; //打开游标 EXEC SQL FETCH C1 INTO :sno, :cno, :score;//推进指针 while (SQLCA.SQLCODE = = SUCCESS) { printf(“sno:%s, cno:%s, Score:%d”, sno,cno,score);//打印 EXEC SQL FETCH C1 INTO :sno, :cno, :score;//推进指针 } CLOSE C1; //关闭游标}
二、ODBC 1、基本概念 ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口)。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。 一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。也就是说,不论是FoxPro、Access还是Oracle数据库,均可用ODBC API进行访问。由此可见,ODBC的最大优点是能以统一的方式处理所有的数据库。
2、一个完整的ODBC由下列几个部件组成: 应用程序(Application)。 ODBC管理器(Administrator)。其主要任务是管理安装的ODBC驱动程序和管理数据源。 驱动程序管理器(Driver Manager)。驱动程序管理器对用户是透明的。其任务是管理ODBC驱动程序,是ODBC中最重要的部件。 ODBC API。 ODBC 驱动程序。是一些DLL,提供了ODBC和数据库之间的接口。 数据源。数据源包含了数据库位置和数据库类型等信息,实际上是一种数据连接的抽象。
3、操作 应用程序要访问一个数据库,首先必须用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。这样,只要应用程序将数据源名提供给ODBC,ODBC就能建立起与相应数据库的连接。 在ODBC中,ODBC API不能直接访问数据库,必须通过驱动程序管理器与数据库交换信息。驱动程序管理器负责将应用程序对ODBC API的调用传递给正确的驱动程序,而驱动程序在执行完相应的操作后,将结果通过驱动程序管理器返回给应用程序。
用户可以定义以下三种类型的数据源: ●用户数据源:作为位于计算机本地的用户数据源而创建的,并且只能被创建这个数据源的用户所使用; ●系统数据源:作为属于计算机或系统而不是特定用户的系统数据源而创建的,用户必须有访问权才能使用; ●文件数据源:指定到文件中作为文件数据源而定义的,任何已经正确地安装了驱动程序的用户皆可以使用这种数据源。
4、利用ODBC DSN来访问数据库: 先通过“控制面板”—“管理工具”—“ODBC数据源”来建立一个数据源名,例如叫做TestData_Resoure。 (1) 通过系统数据源(System DSN)的连接 <% Dim oConn,strConn Set oConn=Server.CreateObject(“ADODB.Connection”) StrConn="DSN=TestData_Resoure;" & _ "Uid=AdminAccount;" & _ "Pwd=PassWord; oConn.Open strConn %>
(2)利用数据库驱动程序直接访问数据库的连接字符串。 例:ODBC Driver for Access 假如数据库(MDB)是网络上共享的,那么连接字符串如下 <% Dim oConn,strConn Set oConn=Server.CreateObject(“ADODB.Connection”) StrConn="Driver={Microsoft Access Driver (*.mdb)};" & _ "Dbq=\\myServer\myShare\myPath\Testdb.mdb;" oConn.Open strConn %>
三、ADO 1、OLE DB OLE DB 建立了数据访问的标准接口,它把所有的数据源经过抽象形成行集(rowset) 的概念。OLE DB 模型主要包括以下一些COM 对象: (1) 数据源(Data Source) 对象数据源对象对应于一个数据提供者,它负责管理用户权限、建立与数据源的连接等初始操作。 (2) 会话(Session) 对象在数据源连接的基础上建立会话对象,会话对象提供了事务控制机制。 (3) 命令(Command) 对象数据使用者利用命令对象执行各种数据操作,如查询命令、修改命令等。 (4) 行集(Rowset) 对象提供了数据的抽象表示,它可以是命令执行的结果,也可以直接由会话对象产生,它是应用程序主要的操作对象。
2、统一数据访问的软件层次模型
OLE DB 是系统级的编程接口,它定义了一组COM 接口,这组接口封装了各种数据系统的访问操作,这组接口为数据使用方和数据提供方建立了标准,OLE DB 还提供了一组标准的服务组件,用于提供查询、缓存、数据更新、事务处理等操作,因此,数据提供方只需实现一些简单的数据操作,在使用方就可以获得全部的数据控制能力。 ADO 是应用层的编程接口,它通过OLE DB 提供的COM 接口访问数据,它适合于各种客户机/ 服务器应用系统和基于Web 的应用,尤其在一些脚本语言中访问数据库操作是ADO 的主要优势。ADO 是一套用自动化技术建立起来的对象层次结构,它比其他的一些对象模型如DAO(Data Access Object)、RDO(Remote Data Object) 等具有更好的灵活性,使用更为方便,并且访问数据的效率更高。
3、ADO 对象模型 (1) ADO 对象模型 ADO 对象模型定义了一组可编程的自动化对象,可用于Visual Basic、Visual C++、Java 以及其他各种支持自动化特性的脚本语言。ADO 最早被用于Microsoft Internet Information Server 中访问数据库的接口,与一般的数据库接口相比,ADO 可更好地用于网络环境,通过优化技术,它尽可能地降低网络流量;ADO 的另一个特性是使用简单,不仅因为它是一个面向高级用户的数据库接口,更因为它使用了一组简化的接口用以处理各种数据源。这两个特性使得ADO 必将取代RDO 和DAO,成为最终的应用层数据接口标准。
(2)Connection 对象: Connection 对象代表与数据源之间的一个连接,ADO 的Connection 对象封装了OLE DB 的数据源对象和会话对象。用法: a. 通过ConnectionString、ConnectionTimeOut 和Mode 属性设置连接串、超时信息、访问模式。 b. 还可以设置CursorLocation 属性以便指定使用客户端游标,以便在客户程序中使用批处理修改方式。 c. 设置连接的缺省数据库属性DefaultDatabase。 d. 设置OLE DB 提供者的属性Provider。 e. 通过Open 和Close 控制Connection 对象与物理数据源的连接。
f. 通过Execute 方法执行命令。 g. 提供事务机制,通过BeginTrans、CommitTrans 和RollbackTrans 方法实现事务控制。 h. 通过Errors 集合属性检查数据源的错误信息。 i. 通过OpenSchema 方法获取数据库的表信息。 如果我们要对数据库进行查询操作,既可以使用Execute 方法,也可以使用Command 对象。使用Execute 方法比较简便,但用Command 对象可以保存命令的信息,以便多次查询。
(3)Command 对象 Command 对象代表一个命令,可以通过其方法执行针对数据源的有关操作,比如查询、修改等。Command 对象的用法如下: a. 通过CommandText 属性设置命令串。 b. 通过Parameters 集合属性和Parameter 对象定义参数化查询或存储过程的参数。 c. 通过Execute 方法执行命令,可能的话,返回Recordset 对象。 d. 在执行命令之前,可通过设置CommandType 属性以便优化性能。 e. 可以通过Prepared 属性指示底层的提供者为当前命令准备一个编译过的版本,以后再执行时,速度会大大加快
f. 通过CommandTimeOut 属性设置命令执行的超时值( 以秒为单位)。 g f. 通过CommandTimeOut 属性设置命令执行的超时值( 以秒为单位)。 g. 可以设置ActiveConnection 属性,为命令指定连接串,Command 对象将在内部创建Connection 对象。 h. 可以设置Name 属性,这样以后可以在相应的Connection 对象上按Name 属性指定的方法名执行。 Command 对象执行时,既可以通过ActiveConnection 属性指定相连的Connection 对象,也可以独立于Connection 对象,直接指定连接串,即使连接串与Connection 对象的连接串相同,Command 对象仍然使用其内部的数据源连接。
(4) Recordset对象 Recordset对象代表一个表的记录集或者命令 执行的结果,在记录集中,总是有一个当前的记录。记录集是ADO管理 数据的基本对象,所有的Recordset对象都按照行列方式的表状结构进 行管理,每一行对应一个记录(Record),每一列对应一个域(Field)。
Recordset对象也通过游标对记录进行访问,在ADO中,游标分为以下4种 : 静态游标提供对数据集的一个静态拷贝,允许各种移动操作,包括 前移、后移等等,但其他用户所做的操作反映不出来。 动态游标允许各种移动操作,包括前移、后移等等,并且其他用户 所做的操作也可以直接反映出来。 前向游标允许各种前向移动操作,不能向后移动,并且其他用户所 做的操作也可以直接反映出来。 键集(keyset)游标 类似于动态游标,也能够看到其他用户所做的 数据修改,但不能看到其他用户新加的记录,也不能访问其他用户删除 的记录。
Recordset对象的用法如下: a.利用CursorType属性设置游标类型。 b.通过Open方法打开记录集数据,既可以在Open之前对ActiveCon nection属性赋值, 指定Recordset对象使用连接对象,也可以直接在O pen方法中指定连接串参数,ADO将创建一个内部连接,即使连接串与外 部的连接对象相同,它也使用新的连接对象。 c.Recordset对象刚打开时,当前记录被定位在首条记录,并且BOF 和EOF标志属性为F alse,如果当前记录集为空记录集,则BOF和EOF标 志属性为True。
d.通过MoveFirst、MoveLast、MoveNext和MovePrevious方法可 以对记录集的游标进行移动操作。如果OLE DB提供者支持相关功能的 话,可以使用AbsolutePosition、Absol utePage和Filter属性对当前 记录重新定位。 e.ADO提供了两种记录修改方式:立即修改和批修改。在立即修改 方式下,一旦调用Update方法,则所有对数据的修改立即被写到底层 的数据源。在批修改方式下,可以对多条记录进行修改,然后调用UpdateBatch方法把所有的修改递交到底层数据源。递交之后,可以用Status属性检查数据冲突。
Recordset对象是ADO数据操作的核心,它既可以作为Connection 对象或Command对象执行特定方法的结果数据集,也可以独立于这两个 对象而使用。 上面3个对象都包含一个Property对象集合的属性,通过Property 对象可使ADO动态暴露出底层OLE DB提供者的性能。由于并不是所有 的底层提供者都有同样的性能,所以ADO 允许用户动态访问底层提供 者的能力。这样既使得ADO很灵活,又提供了很好的扩展性。 ADO的其他集合对象及其元素对象,都用在特定的上下文环境中, 比如Parameter对象一定要与某个Command对象相联系后,才能真正起 作用。而另外三个对象Field、Error和Property对象只能依附于其父 对象,不能单独创建这些对象。
4、连接数据库 Connection对象既可以使用ConnectionString属性建立连接,也可以在Open方法的参数中指定连接串,甚至可以把二者结合起来,如果在Open的参数和ConnectionString属性中同时出现同一个参数信息,则以Open参数信息为准。 下面给出3个典型的连接串例子: (1)在open中指定连接串 Dim Cn As New ADODB.Connection Cn.Open “Provider=SQLOLEDB;User ID=sa;Password=;” & “Initial Catalog=MyDataBase; Data Source=MyServer”
(2)采用连接串 Dim Cn As New ADODB.Connection Cn.ConnectionString = “Provider=SQLOLEDB;User ID=sa;Password=;”&“Initial Catalog= MyDataBase; Data Source=MyServer” Cn.Open (3)采用open方法 Cn.Provider = “SQLOLEDB” Cn.Properties(“User ID”).Value = “sa” Cn.Properties(“Initial Catalog”).Value =“MyDataBase” Cn.Properties(“Data Source”).Value =“MyServer”
5、执行查询的方法 利用ADO执行查询的方法很多,最基本的方法是使用Command对象,也可以直接调用Connection对象的Execute方法。下面介绍使用Command对象执行查询的方 法。 首先建立数据源连接Connection对象,然后创建Command对象: Dim cmd as New ADODB.Command cmd.CommandText =“ Select * from AuthorTable” cmd.Name = “MyCommand” cmd.ActiveConnection = Cn 然后调用Command对象的Execute方法: set rs = cmd.Execute 或者通过Connection对象的方法: set rs = cn.MyCommand
也可以不用Command对象,而是直接使用Recordset 对象,举例如下: Dim rs as New ADODB.Recordset rs.CursorType = adOpenKeyset rs.LockType = adLockOptimistic rs.Open “AuthorTable”, cn, , , adCmdTableset 甚至连Connection对象都可以不使用,直接由Recordset使用内部连接,只需在Open语句中给出必要的连接信息即可。
6、对记录集数据进行操作 对记录集数据进行各种移动或修改操作是应用程序访问数据最重要的任务,与其他一些数据访问接口一样,这些操作集中在记录集对象和域对象的属性和方法调用上,在ADO对象模型中,主要是Recordset和Field对象的一些方法的用法。 增加记录操作:AddNew方法,再调用Update方法,如: rs.AddNew rs!Author_id = strID rs!AuthorName = strName rs!Title = strTitle rs.Update
删除记录操作:调用Delete方法可以删除当前记录或者满足条件的一组记录。在立即修改模式下,删除马上生效;在批修改模式下,Delete操作只在当前缓冲区中的记录上作了标记,只有当调用了UpdateBatch之后,记录才真正被删除。 一个简单的例子如下: rs.Filter = “Title =‘Engineer’” rs.Delete adAffectGroup ’Delete the record. rs.UpdateBatch
修改记录操作:对当前记录的各个域信息进行重新赋值后,调用Update方法,如果要取消修改,则调用CancelUpdate方法。 举例如下: rs!Author_id = strID rs!AuthorName = strName rs!Title = strTitle rs.Update
7、在多种语言中使用ADO (1)在Visual Basic应用中使用ADO Visual Basic应用在设计模式和运行模式下都可以创建和使用自 动化对象,在设计模式下,像ADO这样的对象库可以作为内部对象来使 用,我们只需在“Project”菜单下的“References”命令弹出的对话框 中选中ADO对象库“Microsoft ActiveX Data Objects Library”,于是我们就可以在程序中直接声明或新建ADO对象,举例如下: Dim cn as New ADODB.Connection Dim cmd as New ADODB.Command Dim rs as New ADODB.Recordset
可以看出,在设计时使用ADO对象非常方便,而且Visual Basic设 计环境中提供的对象浏览器(Object Browser)功能允许用户很方便地 查看ADO对象的属性和方法。 我们也可以在运行时创建自动化对象,使用Visual Basic的CreateObject函数可以创建任意的自动化对象,由于ADO中只有Connection 对象、Command对象和Recordset对象可以被独立创建,所以我们也只 能创建这3种对象,举例如下: Dim cn Set rs=CreateObject("ADODB.Connection ") Dim cmd Set rs=CreateObject("ADODB.Command") Dim rs Set rs=CreateObject("ADODB.Recordset") 不管是设计模式还是运行模式,调用ADO对象的属性和方法都非常 简单,直接调用即可。
(2)在ASP的VBScript中使用ADO ADO对象也可以用于HTML和Active Server Page的VBScript脚本 代码,VBScript脚本代码与Visual Basic的代码很类似,它们内嵌在HTML或ASP文件的特定标记对内部。 首先,在VBScript代码中, 没有与设计环境类似的用法,VBScript引擎不能装入ADO类型库,所以 不能使用New操作符创建ADO对象,但可以使用CreateObject函数创建对象;其次,ADO对象库中用到的常量只能通过包含文件引入,随ADO一 起提供的Adovbs.inc文件包含所有ADO常量的定义,我们可在脚本代码中直接包含此文件。 因此为了在VBScript代码中使用ADO,首先要包含Adovbs.inc文 件,然后使用CreateObject函数创建ADO对象,以后就可以调用这些对 象的属性或方法了。
(3)在Visual C++中使用ADO 第一种方法是我们使用CoCreateInstance函数创建ADO对象,并得到对象的IDispatch接口指针,然 后调用其Invoke函数,用这种方法需要我们自己处理参数和返回值,ADO提供了Adoid.h和Adoint.h头文件分别定义了ADO对象的CLSID和接口 ID; 第二种方法是利用#import编译指示符(在Visual C++ 5.0及以后的版本中可以使用),可以方便地使用ADO对象; 第三种方法是利用MFC( Microsoft Foundation Class)库提供的IDispatch接口封装类COleDispatchDriver创建和调用ADO对象。
(4) 在Java中使用ADO 在Java程序中可以引入ADODB类,然后声明ADO变量,也可以使用new操作符创建ADO变量。
四、JDBC 1、加载driver 第一步是在服务器上安装driver。 大多数数据库都有JDBC driver。如果你没有,那么就用Sun的JDBC-ODBC driver。在这种情况下,在服务器上必须装有一个ODBC。 driver的定义是非常简单的。driver文档会给出要用到的class name。 如果使用JDBC-ODBC Bridge driver,那么定义是这样的: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
而如果使用JDBC driver,那么定义是这样的 : Class. forName("jdbc 而如果使用JDBC driver,那么定义是这样的 : Class.forName("jdbc.driver_class_name"); import java.sql.*; /* Loading drivers */ // The JDBC-ODBC Bridge driver Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // mySQL Jdbc driver Class.forName("org.gjt.mm.mysql.Driver"); // Oracle Jdbc driver Class.forName("oracle.jdbc.driver.OracleDriver");
2、创建连接 第二步是在已经加载的driver和数据库之间建立连接。 首先必须创建一个Connection class的实例,其中包括数据库的信息。DriverManager的getconnection()方法将建立在JDBC URL中定义的数据库的connection连接: Connection conn = DriverManager.getConnection(url, login, password); 根据不同的driver, URL的格式可能是不同的。 例如,Oracle提供了2种JDBC drivers : - JDBC Thin for Java applets and applications - JDBC OCI for Java applications 按照所用的JDBC的不同,URL也有所不同。
3、JSP数据库连接方式 以下这种把数据库逻辑全部放在jsp里未必是好的做法,但是有利于初学者学习,当学到一定程度的时候,可以考虑用MVC的模式开发。在练习这些代码的时候,一定将jdbc的驱动程序放到服务器的类路径里,然后要在数据库里建一个表test,有两个字段比如为test1,test2,可以用下面SQL建 create table test(test1 varchar(20),test2 varchar(20) 然后向这个表写入一条测试纪录。
(1)jsp连接Oracle8/8i/9i数据库(用thin模式) testoracle (1)jsp连接Oracle8/8i/9i数据库(用thin模式) testoracle.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl为你的数据库的SID String user="scott"; String password="tiger"; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一个字段内容为:<%=rs.getString(1)%> 您的第二个字段内容为:<%=rs.getString(2)%> <%}%> <%out.print("数据库操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html>
(2)jsp连接Sql Server7. 0/2000数据库 testsqlserver (2)jsp连接Sql Server7.0/2000数据库 testsqlserver.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); String url="jdbc:microsoft: sqlserver://localhost:1433;DatabaseName=pubs"; //pubs为你的数据库的 String user="sa"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一个字段内容为:<%=rs.getString(1)%> 您的第二个字段内容为:<%=rs.getString(2)%> <%}%> <%out.print("数据库操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html>
(3)jsp连接DB2数据库 testdb2.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); String url="jdbc: db2://localhost:5000/sample"; //sample为你的数据库名 String user="admin"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一个字段内容为:<%=rs.getString(1)%> 您的第二个字段内容为:<%=rs.getString(2)%> <%}%> <%out.print("数据库操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html>
(4)jsp连接Informix数据库 testinformix (4)jsp连接Informix数据库 testinformix.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.informix.jdbc.IfxDriver").newInstance(); String url = "jdbc:informix- sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver; user=testuser;password=testpassword"; //testDB为你的数据库名 Connection conn= DriverManager.getConnection(url); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一个字段内容为:<%=rs.getString(1)%> 您的第二个字段内容为:<%=rs.getString(2)%> <%}%> <%out.print("数据库操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html>
(5)jsp连接Sybase数据库 testmysql (5)jsp连接Sybase数据库 testmysql.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("com.sybase.jdbc.SybDriver").newInstance(); String url =" jdbc:sybase:Tds:localhost:5007/tsdata"; //tsdata为你的数据库名 Properties sysProps = System.getProperties(); SysProps.put("user","userid"); SysProps.put("password","user_password"); Connection conn= DriverManager.getConnection(url, SysProps); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一个字段内容为:<%=rs.getString(1)%> 您的第二个字段内容为:<%=rs.getString(2)%> <%}%> <%out.print("数据库操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html>
(6)jsp连接MySQL数据库 testmysql (6)jsp连接MySQL数据库 testmysql.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("org.gjt.mm.mysql.Driver").newInstance(); String url ="jdbc: mysql://localhost/softforum?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1" //testDB为你的数据库名 Connection conn= DriverManager.getConnection(url); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一个字段内容为:<%=rs.getString(1)%> 您的第二个字段内容为:<%=rs.getString(2)%> <%}%> <%out.print("数据库操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html>
(7)jsp连接PostgreSQL数据库 testmysql (7)jsp连接PostgreSQL数据库 testmysql.jsp如下: <%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*"%> <html> <body> <%Class.forName("org.postgresql.Driver").newInstance(); String url ="jdbc: postgresql://localhost/soft" //soft为你的数据库名 String user="myuser"; String password="mypassword"; Connection conn= DriverManager.getConnection(url,user,password); Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from test"; ResultSet rs=stmt.executeQuery(sql); while(rs.next()) {%> 您的第一个字段内容为:<%=rs.getString(1)%> 您的第二个字段内容为:<%=rs.getString(2)%> <%}%> <%out.print("数据库操作成功,恭喜你");%> <%rs.close(); stmt.close(); conn.close(); %> </body> </html>
五、各种数据库连接方式的比较 1、 DAO和ODBC DAO和ODBC的工作原理差别较大。ODBC原本是通过ODBC API调用的,但VB的DAO和RDO都封装了ODBC,所以,在VB中应用起来感觉差别不大,调用的时候只是在指定驱动时有所不同,一般的数据库操作差不多。DAO是针对VB/Access设计的,VC 4.0以后也开始使用,它所支持的数据库类型就是VB的那几种,很少见第三方驱动程序。ODBC是开放的数据库接口,几乎支持所有数据库类型,对于很多VB不能很好地支持的数据库类型,如Visual FoxPro 5.0,都可以使用ODBC驱动。一般来说DAO支持本机Access数据库比较理想,但在客户/服务器体系上不如ODBC功能强大。
2、OLE DB和ODBC 由于ODBC相对OLE DB来说使用得更为普遍,因此可以获得的ODBC驱动程序相应地要比OLE DB的要多。这样不一定要得到OLE DB的驱动程序,就可以立即访问原有的数据系统。 如果想使用一个ODBC数据源,需要使用针对ODBC的OLE DB提供者,它会接着使用相应的ODBC驱动程序。如果不需要使用ODBC数据源,那么可以使用相应的OLE DB提供者,这些通常称为本地提供者(native provider)。 可以清楚地看出使用ODBC提供者意味着需要一个额外的层。因此,当访问相同的数据时,针对ODBC的OLE DB提供者可能会比本地的OLE DB提供者的速度慢一些。
第四章 关系规范化 关系SDC(SNO,SNAME,DNAME, DADDR, CNO, CNAME, SCORE) 存在着三大问题: 第四章 关系规范化 关系SDC(SNO,SNAME,DNAME, DADDR, CNO, CNAME, SCORE) 存在着三大问题: 1、数据冗余 2、插入异常 3、删除异常
第一节 函数依赖 一、函数依赖概念 1、函数依赖:设有关系模式R(A1,A2,……,AK),X和Y 均为{A1,A2,……,Ak}的子集,r是R的任一具体关系(R代表型,r代表值),U,V是r中的任意两个元组。如果由U[X]=V[X]能导致U[Y]=V[Y],则称X函数决定Y,或Y 函数依赖于X,记为XY。其中,U[X]表示元组U在X上的属性值,V[X]、U[Y]、V[Y]有类似的意义。 若XY, 则称X为决定因素。 SNOSNAME (SNO,CNO)SCORE
2、平凡函数依赖:由于若Y属于X,则一定有XY,这种依赖为平凡的函数依赖。 (SNO, CNO)CNO 3、完全函数依赖 定义:在关系模式R(U)中,如果XY,并且对于X的任何一个真子集 ,都有 Y,则称Y完全函数依赖于X,记为X > Y。 (SNO,CNO) > SCORE 4、部分函数依赖 定义:如果XY,但Y不完全函数依赖于X,则称Y部分函数依赖于X,记为X Y。 (SNO,CNO) SNAME
5、传递函数依赖 定义:在关系模式R(U)中,如果XY,YZ,且Y X, Y X,则称Z传递函数依赖于X。 在关系SDC中, SNODNAME,DNAMEDADDR, 且DNAME SN0, DNAME SNO, 所以,DADDR传递函数依赖于SNO。
二、码 1、候选码------若K 关系R的属性集,则K为R的候选码。 如 SDC中的(SNO,CNO) 2、主码------选定多个候选码之一作为主码。 3、主属性------任一候选码中的属性。 如SDC中的SNO。 4、非主属性------不包含在任何候选码中的属性。 如SDC中的DADDR, SCORE 5、全码------整个属性组为码。 6、外部码------若X 为R的码而X 在G中不是码,则称X为G的外部码。
第二节 关系规范化 一、范式 1、范式是符合某一种级别关系模式的集合。关系数据库中的关系必须满足一定的要求,才能尽量减少数据依赖对关系模式的影响。满足不同程度要求的为不同的范式。目前主要有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、BC范式(BCNF)、第四范式(4NF)、第五范式(5NF)。 2、各范式之间存在如下关系: 1NF 2NF 3NF BCNF 4NF 5NF 也就是说,第一范式满足最低的要求,在第一范式中进一步满足一些要求的为第二范式,其余依此类推。 3、一个低一级范式的关系模式,通过投影运算可以转换为若干个高一级范式的关系模式的集合,这种过程就叫关系规范化。
二、第一范式 1、定义:如果一个关系模式中的每个属性值都是不可再分的基本元素,则称该关系模式是第一范式(1NF),记为R 1NF。 2、例 姓名 课程名 成绩 平时成绩 考试成绩 刘阡 操作系统 90 87 计算机软件基础 85 95 王芳 80 数据库系统原理 92 张泉
4、第一范式的关系模式存在冗余、修改不易、插入异常、删除异常等问题。 姓名 课程名 平时成绩 考试成绩 刘阡 操作系统 90 87 3、 非第一范式的关系模式很容易转化为第一范式。 4、第一范式的关系模式存在冗余、修改不易、插入异常、删除异常等问题。 姓名 课程名 平时成绩 考试成绩 刘阡 操作系统 90 87 计算机软件基础 85 95 王芳 80 数据库系统原理 92 张泉
三、第二范式 1、定义:若关系模式R是第一范式,且每个非主属性都完全依赖于R的码,则称R是第二范式,记为R 2NF。 在关系SDC中,SNAME不完全函数依赖于码(SNO,CNO),所以SDC不是第二范式。 2、可以通过投影分解将关系SDC分解成若干个2NF的关系模式。具体步骤如下: (1)分析关系中各非主属性对主属性和码的函数依赖关系。 (2)将函数依赖于同一主属性的各非主属性分为一组,作为一个关系模式,其码是原主属性。 (3)将完全函数依赖于同一组主属性的余下的各非主属性分为一组,作为一个关系模式,其码是该组主属性。 (4)将完全函数依赖于码的余下的非主属性作为一组,其码为原码。
按照上述步骤,分析关系SDC中的依赖关系如下: 3、例: 按照上述步骤,分析关系SDC中的依赖关系如下: 关系SDC可以分解为三个关系模式 SD(SNO,SNAME,DNAME,DADD) C(CNO,CNAME) SC(SNO,CNO,SCORE) 关系SD、C、SC都是2NF。 4、2NF的关系仍然存在着冗余、修改不易、插入异常、删除异常等问题。
四、第三范式 1、定义:如果关系R是2NF,且其非主属性之间不存在函数依赖,即没有任一个非主属性函数依赖于另一个非主属性,则称该关系模式是3NF。 2、3NF的关系既不存在非主属性对码的部分函数依赖,也不存在非主属性对码的传递函数依赖。 3、例:关系SD的码为学号,由于存在着函数依赖 DNAMEDADDR 而DNAME、DADDR都是非主属性,所以关系SD不是3NF。可以通过投影分解将关系SD分解为: S(SNO,SNAME,DNAME) D(DNAME,DADDR) 关系S、D都是3NF。
五、BCNF范式 1、定义:每一个决定因素都包含码的3NF为BCNF。 2、例:对于关系模式SP(SNO,CNO,CNAME,SCORE),假设CNAME不可相同,那么(SNO,CNO)和(SNO,CNAME)都是关系模式SP的码,SNO、CNO、CMAME都是主属性,SCORE是非主属性。显然,关系模式SP是第三范式。由于存在函数依赖 CNOCNAME CNAMECNO 所以关系模式SP不是BCNF。可分解为 SN(CNO,CNAME) SPC(SNO,CNAME,SCORE) 关系模式SN和SPC都是BCNF。 3、BCNF在函数依赖范围内已经实现了模式的彻底分解,达到了最高的规范化程度,基本消除了插入异常和删除异常。
六、多值依赖 1、定义:对一个关系模式的任意一个可能关系,如果其中两个元组在X属性上的值相等,且交换这两个元组在Y属性上的值而得到的两个新元组仍在这个关系中,则称Y多值依赖于X,记为X->Y。 2、例: 关系模式 SCB(CNAME, TEACHER, BOOK) CNAME->TEACHER 3、非平凡的多值依赖: 若X->Y, 且X U Y<>U, 则称X->Y为非平凡的多值依赖,否则为平凡的多值依赖。
CNAME TEACHER BOOK OS 张三 操作系统 李四 Linux DBMS 数据库系统 数据库原理 SQL Server 2000 王五 马六
七、4NF 1、定义:若关系R中只要有多值依赖,其决定因素必包含码,则R为4NF。 2、非4NF的关系模式冗余大。 关系SDB不是4NF。 3、将非4NF的关系模式规范化到4NF 若非4NF的关系模式R存在着多值依赖X->Y, 可将非4NF的关系模式分解为两个模式: (1)X和Y (2)X和R中除了Y 的所有属性 其结果都为4NF。
第三节 关系模式的分解 一、定义 设R是一个关系,Ri, i=1, 2, …, k是R的子集,如果R1UR2U…URk=R, 则称ρ={R1, R2, …, Rk}为关系模式R的一个分解。 二、分解的等价性 1、无损连接性------ 可通过对分解后形成的关系的某种连接运算使之还原到分解前的关系。 2、保持函数依赖性------分解过程中不能丢失或破坏原有关系的函数依赖。 三、关系的分解不是唯一的。
四、关系的规范化程度 关系的规范化程度越高,关系模式的数量也就越多。这样,对于某些原本可以在一个和较少关系模式上执行的操作,现在可能要在多个关系模式上进行,这不仅使得程序编制更复杂,而且执行效率往往会受到较大的影响。在实际应用中,设计人员应根据具体应用需求,灵活掌握关系规范化的程度。
第五章 数据库保护 第一节 安全性 一、概念 1、定义:保护数据库以防止不合法的使用所造成的数据泄露、更改或破坏。 第五章 数据库保护 第一节 安全性 一、概念 1、定义:保护数据库以防止不合法的使用所造成的数据泄露、更改或破坏。 2、目标:企图破坏安全的人所花费的代价应远远超出它们所得到的利益。 二、安全性控制的一般方法 1、用户识别 2、密码转换 3、存取控制
三、角色与授权 1、角色:拥有同样存取权限的某一类用户。 2、授权:将某些权限授予或传递给某一角色或用户。 四、ORACLE的权限控制 1、DBA专用的授权 CONNECT GRANT RESOURCE TO 用户名 [IDENTIFED BY 口令]; DBA
2、用户可用授权 SELECT INSERT 关系名 用户名 GRANT UPDATE (属性名列) ON TO ALTER 视图名 PUBLIC INDEX ALL [ WITH GRANT OPTION ]
四、ORACLE的授权 1、创建角色 CREATE ROLE 角色名 [ IDENTIFIED BY 口令 ] 例:CREATE ROLE ROLE_PRODUCT; 2、角色删除 DROP ROLE 角色名; 例:DROP ROLE ROLE_PRODUCT;
3、授权 例: GRANT CREATE SESSION, ALTER SESSION TO ROLE_PRODUCT; GRANT SELECT, INSERT, UPDATE, DELETE ON PRODUCT_MASTER TO ROLE_PRODUCT; GRANT CONNECT, RESOURCE, DBA TO SMITH; 4、授权的撤销 REVOKE { 特权|ALL } [ON OBJECT ] FROM { 用户|角色|PUBLIC } REVOKE UPDATE ON PRODUCT_MASTER FROM ROLE_PRODUCT;
第二节 数据库完整性 一、概念 1、数据库的完整性------数据的正确性、有效性 2、完整性约束------用以检查数据的正确、有效的条件 第二节 数据库完整性 一、概念 1、数据库的完整性------数据的正确性、有效性 2、完整性约束------用以检查数据的正确、有效的条件 二、完整性约束条件 1、值的约束和结构的约束 2、静态约束和动态约束 3、立即执行约束和延迟执行约束
三、SQL的完整性 1、参照完整性 (1)外码说明 [ FOREIGN KEY ] [( 列名[{,列名}])] REFERENCES 表名 [(参照列名[{,参照列名}])] 表明外码值必出现在另一关系中。 例: CREATE TABLE OPERATOR_INFO ( OPERATOR_CODE VARCHAR(30) PRIMARY KEY, OPERATOR_NAME VARCHAR(32) NOT NULL, OPERATOR_RIGHT VARCHAR(15), OPERATOR_PASSWORD VARCHAR(15) NOT NULL );
SYS_NAME VARCHAR(20) PRIMARY KEY, SYS_VALUE VARCHAR(50), CREATE TABLE SYS_CONFIG ( SYS_NAME VARCHAR(20) PRIMARY KEY, SYS_VALUE VARCHAR(50), LOGIN_DATE DATE , LAST_DATE DATE , OPERATOR_CODE VARCHAR(30) REFERENCES OPERATOR_INFO(OPERATOR_CODE) );
CREATE TABLE COUNTRY_INFO ( COUNTRY_CODE VARCHAR(4) PRIMARY KEY, COUNTRY_NAME VARCHAR(32) , COUNTRY_ENGNAME VARCHAR(32), LOGIN_DATE DATE, LAST_DATE DATE, OPERATOR_CODE VARCHAR(30) REFERENCES OPERATOR_INFO(OPERATOR_CODE) );
(2)保持参照完整性 ① 隐含规则:避免引起冲突的修改。 ② 级联规则:在删除或修改某一项时,必须删除或修改其参照元组。 例: CREATE TABLE COUNTRY_INFO ( COUNTRY_CODE VARCHAR(4) PRIMARY KEY, COUNTRY_NAME VARCHAR(32) , COUNTRY_ENGNAME VARCHAR(32), LOGIN_DATE DATE, LAST_DATE DATE, OPERATOR_CODE VARCHAR(30) REFERENCES OPERATOR_INFO(OPERATOR_CODE) ON DELETE SET NULL ON UPDATE CASCADE ); ③ 置空规则:在删除或修改参照元组时,置对应外码为空。
2、用户定义的完整性 (1)非空限制 CREATE TABLE STUDENT ( SNO VARCHAR(6) PRIMARY KEY, SNAME VARCHAR(20) NOT NULL, SEX CHAR(2) , SROOM VARCHAR(10) ) ; 非空限制表明字段: ①值非空; ②无此值时不能插入; ③在此值上不能使用置空规则;
(2)属性检查 语法: [ CONSTRAINT 约束名] CHECK [NOT FOR REPLICATION] (逻辑表达式) 例: CREATE TABLE GRADE( PRIMARY KEY(SNO, CNO), SNO NUMBER(10), CNO NUMBER(10), SCORE NUMBER(3,0) CHECK (SCORE>=0 AND SCORE<=100) );
最基本的完整性约束。允许指定一个谓词,对类型属于该域的变量所赋的任意值都必须满足该谓词。 (3)域约束 最基本的完整性约束。允许指定一个谓词,对类型属于该域的变量所赋的任意值都必须满足该谓词。 语法:CREATE DOMAIN 字段名 数据类型 CONSTRAINT 约束名 CHECK 条件 例: CREATE DOMAIN SCOREDOMAIN NUMBER(3,0) CONSTRAINT SCORE_FIELD CHECK (SCORE>=0 AND SCORE<=100) CREATE DOMAIN SNAME VARCHAR(20) CONSTRAINT SNAME_FIELD CHECK (VALUE NOT NULL)
3、实体完整性 (1)元组检查 对关系中的多个属性的约束。 CREATE TABLE GRADE ( PRIMARY KEY(SNO, CNO), SNO NUMBER(10), CNO NUMBER(10), SCORE NUMBER(3,0), CHECK (SCORE>=0 AND SCORE<=100 AND CNO>100) );
(2)断言 涉及整个关系或同一关系中的多个元组变量的约束 语法:CREATE ASSERTION 断言名 CHECK 断言 例: CREATE ASSERTION EXSTUDENT CHECK (NOT EXISTS (SELECT * FROM STUDENT,SC WHERE STUDENT.SNO=SC.SNO AND SCORE<70) );
四、约束 1、约束的命名 语法:CONSTRAINT 约束名 CHECK 约束条件 例: SEX VARCHAR(2) CONSTRAINT SEXVALUE CHECK (SEX IN (‘男’,‘女’)), SCORE NUMBER(3,0), CONSTRAINT GRADE CHECK (SCORE>=0 AND SCORE<=100 AND CNO>100) CREATE DOMAIN SNAME VARCHAR(20) CONSTRAINT SNAME_FIELD CHECK (VALUE IN (“张山”,“李四”)) CREATE SNO VARCHAR(20) CONSTRAINT ISKEY PRIMARY KEY,
2、约束的修改 语法: 删除:ALTER TABLE 表名 DROP CONSTRAINT 约束名; 增加:ALTER TABLE 表名 ADD CONSTRAINT 约束名; 例: ALTER TABLE SC DROP CONSTRAINT GRADE; ALTER TABLE SC ADD CONSTRAINT ISKEY PRIMARY KEY(SNO); ALTER TABLE SC ADD CONSTRAINT GRADE CHECK (SCORE>=0 AND SCORE<=100 AND CNO>100);
3、修改域约束 语法: 增加:ALTER DOMAIN 域名 ADD CONSTRAINT 域约束名 约束条件; 例: ALTER DOMAIN SCOREDOMAIN ADD CONSTRAINT SVALUE CHECK (SCORE>=0 AND SCORE<=100); 删除:ALTER DOMAIN 域名 DROP CONSTRAINT 域约束名; ALTER DOMAIN SCOREDOMAIN DROP CONSTRAINT SVALUE;
4、修改断言 语法: DROP ASSERTION 断言名; 例: DROP ASSERTION EXSTUDENT; 5、默认值 DEFAULT 默认值
CREATE TABLE COUNTRY_INFO ( COUNTRY_CODE VARCHAR2(4) PRIMARY KEY, COUNTRY_NAME VARCHAR2(32) , COUNTRY_ENGNAME VARCHAR2(32), LOGIN_DATE DATE, LAST_DATE DATE DEFAULT SYSDATE, OPERATOR_CODE VARCHAR2(30) REFERENCES OPERATOR_INFO(OPERATOR_CODE) );
五、完整性实现 1、系统提供定义完整性约束条件的功能 2、提供检查完整性约束条件的方法
第三节 并发控制 一、事务 1、概念:是一个不可分割的操作序列。一个程序或一段程序的一次单独执行。 2、ORACLE的事务: 第三节 并发控制 一、事务 1、概念:是一个不可分割的操作序列。一个程序或一段程序的一次单独执行。 2、ORACLE的事务: (1)一个事务由COMMIT或ROLLBACK作为结束,同时也作为下一个事务的开始。 (2)当进入SQL*PLUS时,一个事务即告开始。 (3)当退出或中断ORACLE时,当前事务自动宣告结束。 (4)有些SQL语句如CREATE、DROP一旦被执行,即自动提交,而无需执行COMMIT语句。 (5)用户所作的任一个数据操作,都在且仅在一个事务之中。
3、事务状态 事务必须处于以下状态之一: (1)活动状态:初始状态,事务执行时处于这个状态。 (2)部分提交状态:最后一条语句被执行之后。 (3)失败状态:发现正常的执行不能继续后。 (4)中止状态:事务回滚并且数据库已被恢复到事务开始执行前的状态后。 (5)提交状态:成功完成后。 成功完成执行的事务称为已提交事务。 提交的或中止的事务称为已结束事务。
部分提交状态 提交状态 活动状态 中止状态 失败状态
为了保证数据的完整性,数据库系统应该具有: 4、ACID特性 为了保证数据的完整性,数据库系统应该具有: 原子性Atomicity . 事务的所有操作在数据库中要么全部正确反映出来要么完全不反映. 一致性Consistency . 事务的隔离执行(即没有并发执行的其他事务)保证数据库的一致性. 隔离性Isolation . 尽管多个事务可以并发执行,当系统必须保证对任一事务对Ti和Tj ,在 Ti看来,Tj 或者在Ti开始之前已经停止执行,或者在Ti 完成之后开始执行。这样每个事务都感觉不到系统中有其他事务在并发执行。 持久性Durability . 一个事务成功完成后,它对数据库的改变必须是永久的,即使系统可能出现故障。
例:事务将50元从账户A 转入账户 B: 1. read(A) 2. A := A – 50 3. write(A) 4. read(B) 5. B := B + 50 6. write(B) 一致性要求–A 和 B金额之和不会被执行结果改变。 原子性要求 — 如果事务在第 3步和第 6步之间失败,系统保证修改不会反映在数据库中。 持久性要求 — 一旦修改已经完成 (i.e., 50元的转账成功), 事务对数据库的修改就一直保留,任何系统故障都不会引起与这次转账相关的数据的丢失。 隔离性要求 — 如果在第 3步和第 6步之间,允许另一个事务去存取部分修改了的数据库, 会导致不一致的状态,所以隔离性确保并发执行的事务和串行执行的事务结果等价。
5、事务控制 (1)提交 COMMIT (2)撤销 ROLLBACK 6、实例 创建一个触发器,它的作用就是更新的时候禁止修改主键。 create trigger publishers_Utg on publishers for update as if update( pub_id ) begin print “You cannot Update the primary key!” rollback transaction return end publishers_Utg;
二、并发操作 1、并发操作可能导致的问题 (1)丢失修改 (2)不能重复读 (3)污读 2、并发控制:用正确的方式调度并发控制,避免造成数据的不一致性。 3、并发控制的主要方法:封锁机制 大:开销小,并发度低 范围 小:开销大,并发度高
-------------------------------------------------------- T1 T2 T1 T2 T1 T2 -------------------------------------------------------- 读A=5 读A=5 读A=5 读A=5 A=A-1 读A=5 A=A-1 读A=4 A=A-1 A=A-1 撤销 T1 读A=4 A=5 丢失修改 污读 不能重复读
三、封锁 1、概念:事务可向系统发出请求,对某个数据对象加锁,取得对这个数据对象的一定的控制权。 2、类型 共享锁 种类 排他锁 3、数据库的并发控制的封锁机制: 对被操作的数据加锁,操作完毕后要解锁。 4、封锁的对象:逻辑单元,物理单元 例:在关系数据库中,封锁对象: 逻辑单元: 属性值、属性值集合、元组、关系、索引项、整个索引、整个数据库等 物理单元:页(数据页或索引页)、物理记录等
4、封锁协议的级别 (1)1级封锁协议------对事务T要修改的数据R加X锁,直到事务结束为止。 可防止丢失修改并保证事务T可恢复。 (2)2级封锁协议------1级封锁协议加上对T要读取的数据R加S锁。 防止读脏数据。 (3)3级封锁协议------1级封锁协议加上对T要读取的数据R加S锁,直到事务结束才释放。 保证可重复读。
T1 T2 T1 T2 T1 T2 -------------------------------------------------------- Xlock A Xlock A Slock A 读A=5 读A=5 读A=5 Xlock A A=A-1 Xlock A 等待 Slock A 等待 等待 A=A-1 撤销 T1 读A=5 UNLOCK A UNLOCK A UNLOCK A 获得 获得 获得 Xlock A Slock A Xlock A 读A=4 读A=5 读A=5 A=A-1 A=A-1 UNLOCK A UNLOCK A 1级封锁协议 2级封锁协议 3级封锁协议 Read Uncommitted Read Committed Read Repeatable (Sql Server 默认)
四、可串行性 1、并行事务的不同调度实例 2、可串行化定义------当且仅当某组事务的一定交叉调度产生的结果和这些事务的某一串行调度的结果相同,则称这个交叉调度是可串行化的。 3、两段锁协议: (1)扩展阶段:获得锁 (2)收缩阶段:释放锁 两段锁协议保证的是可串行性,不能避免死锁的发生。 Read Serializable
----------------------------------------———————————- T1 T2 T1 T2 T1 T2 ----------------------------------------———————————- 读A=5 读A=5 读A=5 A=A-1 读B=7 A=A-1 读B=7 A=A-1 读B=7 B=B-2 读B=7 B=B-4 写B(5) B=B-2 写B(3) 读B=5 写B(5) 读B=3 B=B-4 B=B-4 B=B-2 写B(1) 写B(3) 写B(1) 串行调度 不可串行化 可串行化
在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同: ◆未授权读取(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。 ◆授权读取(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。 ◆可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
◆序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为 Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别 场合,可以由应用程序采用悲观锁或乐观锁来控制。
五、活锁和死锁 1、活锁------某一事务由于某种原因总是得不到机会加锁。 解决方法之一:先来先服务 2、死锁------循环等待锁。 解决方法: (1)每一事务一次申请所需的所有锁。 (2)给所有的数据对象规定一个线性顺序,要求每一个事务按这个次序申请它所需的锁。 (3)事先根本不预防死锁的产生,而是周期性地检查。如果有死锁存在,至少让其中一个事务重新启动,而且它对数据库产生的影响必须被撤销。
第六章 数据库设计 第一节 概述 一、概念 1、数据库设计------从用户对数据的需求出发,研究并构造数据库结构的过程。 2、数据库结构 第六章 数据库设计 第一节 概述 一、概念 1、数据库设计------从用户对数据的需求出发,研究并构造数据库结构的过程。 2、数据库结构 (1)数据库的逻辑结构 (2)数据库的物理结构 3、数据库设计目标 (1)满足应用功能需求 (2)良好的数据库性能
二、特点 1、是一项软件工程 2、必须具备多方面的知识 三、数据库设计方法 1、有效的数据库设计方法 (1)在合理时间、合理工作量情况下,产生具有实用价值的数据库结构。 (2)足够的通用性和灵活性,适用于不同的领域、DBMS和数据库设计人员。 (3)可再生产。
2、生存期:数据库系统从开始规划到最后被新的系统取代而停止使用的整个期间。 按规范设计的方法可将数据库设计分为以下六个阶段:
3、数据库设计的各个阶段 设计阶段 设计描述 数据 处理 需求分析 数据字典、系统中数据项、数据流、数据存储的描述 数据流图、判定树(判定表)、数据字典中处理过程的描述 概念结构设计 概念模型 数据字典 系统说明书,包括: 系统要求、方案和概图 反映新系统信息流的数据流图 逻辑结构设计 基本数据模型(层次、网状或关系) 系统结构图(模块结构图) 物理设计 存储安排 存取方法选择 存取路径建立 模块设计 IPO表 实施 编写模式 装入数据 数据库试运行 程序编码 编译链接 测试 运行和维护 性能监测 转储/恢复 数据库重组和重构 新旧系统转换、运行、维护
第二节 规划论证 一、初步综合调查 二、对现行系统数据管理的分析 三、规划设计 四、可行性分析论证
第三节 需求分析 一、主要任务 通过听取数据库应用部门工作人员的报告并与之座谈、查阅原始资料及跟班作业等方法,对待定的数据库完成用户需求调查,确定数据库的目标、结构及用户界面。 二、用户对数据库的要求: 1、信息要求------用户将从数据库中获得信息的内容、性质。由信息要求导出数据要求,确定数据库中需存储的数据。 2、处理要求------用户要完成的处理功能、对处理要求的响应时间、处理的方式是批处理还是联机处理。 3、安全性和完整性的要求------允许哪些用户对于哪些数据对象执行哪些类型的操作。以及为防止数据库中存在不合语义的数据和错误的输入、输出所造成的无效操作和错误结果所设置的约束条件。
三、需求分析的具体步骤: 1、确定数据库范围——确定数据库应支持哪些应用功能。 2、数据应用过程分析——了解并分析数据与数据处理间的关系。 3、数据收集与分析——分析了解数据的组成、操作特征、语义和关系。 4、文档整理——需求说明书的整理。 四、结构化分析方法: 1、分析方式------采用自顶向下、逐层分解的方式分析系统。 2、分析工具------用数据流图、判定树或判定表和数据字典描述系统。 五、需求分析的要求: 1、需求分析必须考虑将来应用的要求------如果设计人员仅仅根据当前应用来设计数据库,以后再想加入新的实体、属性和联系就会十分困难。 2、需求分析必须强调用户的参与------用户的积极参与不仅可以加快调查分析的速度,也大大提高了调查研究的质量,对以后的数据库设计工作打下了良好的基础。
第四节 概念结构设计 一、任务: 1、内容:在需求分析中产生的需求说明书的基础上,按照特定的方法抽象和合成满足应用需求的用户信息结构,即概念模型。 2、目标:最大限度地满足应用需求,可以完全不顾及具体的软、硬件限制,特别是DBMS的限制。 二、方法: 1、自顶向下。先定义全局概念的框架,然后逐步细化。 2、自底向上。先通过分类、聚集、概括等方法定义各局部应用的概念结构,然后再处理各局部模式对各种对象定义的不一致和冗余问题,集成得到全局概念结构。 3、混合策略。自顶向下与自底向上相结合。
三、采用E-R方法的自底向上概念模式设计的主要步骤:
2、设计全局E-R模型
3、局部E-R模式之间的冲突有三类: (1)属性冲突。 包括属性值的类型、取值范围等的冲突和取值单位的冲突。例如,有的局部E-R模式用字符表示身份证号,有的局部E-R模式又用数字表示。有的局部E-R模式用公斤作重量的计量单位,有的局部E-R模式又用磅作重量的计量单位。这类冲突可以通过讨论、协商等行政手段来解决。 (2)结构冲突。 包括同一对象在不同的应用中的不同抽象、同一实体在不同E-R图中属性组成不同和实体联系类型在不同E-R分图中不同。例如,有的局部E-R模式将成绩单作为实体,有的局部E-R模式将成绩单作为联系;有的应用中讲课是一对多的联系,而有的应用中讲课是多对多的联系。结构冲突需要通过对应用的认真分析,分别采用不同方法解决。 (3)命名冲突。 包括属性名、实体名、联系名的同名异义和同义异名。这类冲突也可以通过讨论协商解决。
4、合并与优化 (1)合并 合并从公共实体类开始,最后再把独立的局部结构加进去。一般先合并那些现实世界中有联系的局部结构。合并时可以两两合并,也可以多个模式同时合并。 (2)优化 当所有局部E-R模式都已合并后,可以采用分析方法或规范化的方法优化全局E-R模式,消除不必要的冗余。优化的任务是使实体类的个数尽可能少,实体类所含属性的个数尽可能少,实体类之间联系无冗余 。
第五节 逻辑结构设计 一、内容: 1、任务 根据系统确定的数据库管理系统软件支持的功能,将全局概念模式转换成相应的数据模型。所设计出的逻辑结构应保证数据共享和数据的逻辑独立性,有利于数据的完整性和安全保密,消除结构冗余,降低数据库开销。 2、设计过程 可以分为三步,首先将概念结构转换为一般的关系、网状或层次模型,然后向特定的数据库管理系统支持下的数据模型转换,最后对数据模型进行优化。
二、E-R图向关系数据模型的转换。 1、任务 关系模型的逻辑结构是一组关系模式的集合。而E-R图则是由实体、实体的属性和实体之间的联系组成的。所以将E-R图转换为关系模型实际上就是要将实体、实体的属性和实体之间的联系转换为关系模式。 2、原则 这种转换一般应遵循如下原则: (1)一个实体型转换为一个关系模式。实体的属性就是关系的属性。实体的码就是关系的码。 (2)一个联系转换为一个关系模式。与该联系相连的各实体的码以及联系的属性转换为关系的属性。 (3)具有相同码的关系模式可以合并。
一个实体型转换为一个关系模式: 系(系名,地址,系主任) 学生(学号,姓名,班级,专业) 教师(姓名,教研室,职称) 课程(课程名,课时) 一个联系转换为一个关系模式: 管理(系名,姓名) 注册(系名,学号) 选修(课程名,学号,成绩) 讲授(姓名,课程名)
第六节 物理设计 一、确定数据的存储结构。 根据对存取时间、存储空间利用率和维护代价的考虑从数据库管理系统所提供的存储结构中选取一种合适的存储结构。 二、存取路径的选择和调整。 数据库必须支持多个用户的多种应用,因而必须提供对数据库的多个存取入口,也就是对同一数据存储要提供多条存取路径。物理设计应确定建立哪些存取路径。 三、确定数据存放位置。 为了提高系统性能,数据应该根据应用情况将易变部分与稳定部分、经常存取部分和存取频率较低部分分开存放。首先按数据的应用情况划分为不同的组,然后确定存放位置。经常存取或存取时间要求高的数据应存放在高速存取器如硬盘上。存取频率低、数据量大或存取时间要求低的数据可以放在低速存储器如软盘、磁带上。
四、确定存储分配参数。 数据库管理系统一般都提供了一些存储分配的参数供设计人员和数据库管理员对数据库进行物理优化处理。虽然系统都为这些参数赋予了合理的缺省值,但是这些值不一定适合每一种应用环境。在对数据库进行物理设计时,可能需要根据应用的具体情况对这些参数重新赋值以改善系统的性能。这些参数包括:同时使用数据库的用户数、同时打开数据库的个数、使用的缓冲区的大小和个数、时间片的大小、数据库的大小、装填因子等等。这些参数的大小影响存取时间和存储空间的分配。
第七节 数据库实施 一、创建数据库。 运用数据库管理系统提供的命令创建数据的结构,将数据库结构定义映像到内存中。 二、数据库模拟。 第七节 数据库实施 一、创建数据库。 运用数据库管理系统提供的命令创建数据的结构,将数据库结构定义映像到内存中。 二、数据库模拟。 确定模拟试验的目标,选择一定量的典型数据装入数据库,然后按照确定的目标运行系统,对运行结果分析评价,根据分析结果调整结构及性能,运行调整后的系统,再作分析评价,直到满意为止。 三、数据库加载。 对经过模拟试验的数据库可以进行大批量数据加载。对于数据量不是很大的小型系统,可以用人工方法完成数据库的加载。通过将分散在各个部门的数据文件或原始凭证中的数据筛选出来、将数据转换成符合数据库要求的格式、再将转换好的数据输入计算机中、最后检查输入的数据是否正确无误。
四、编制与调试和试运行部分应用程序。 当数据库结构建立好之后,就可以开始编制与调试数据库的应用程序。通过实际运行应用程序,执行对数据库的各种操作,测试系统的功能和性能指标,分析是否符合设计目标。如果实际结果不符合用户要求,则需返回物理设计阶段,调整物理结构,修改参数。有时甚至需要返回逻辑设计阶段,调整逻辑结构。
第八节 数据库的运行与维护 一、数据库的安全性控制。 第八节 数据库的运行与维护 一、数据库的安全性控制。 保护数据库的安全就是防止恶意的破坏和非法的使用。在数据库运行期间,由于应用环境的变化,对安全性的要求也会变化。因此需要根据不同用户的实际需要修改他们的操作权限或密级。 二、数据库的完整性控制。 完整性控制是防止数据库中存在不合语义的数据和错误的输入/输出所造成的无效操作和错误结果。在数据库运行阶段往往需要增加新的完整性约束条件或修改旧的完整性约束条件,以满足用户要求。
三、数据库的转储和恢复。 数据库的转储和恢复是系统正式运行后最重要的维护工作之一。要针对不同的应用要求制定不同的转储计划,定期对数据库和日志文件进行备份,以保证一旦发生故障,能够利用数据库备份及日志文件备份,尽快将数据库恢复到某种已知的正确状态,并尽可能减少对数据库的破坏。 四、数据库的重组和重构。 数据库运行一段时间后,由于记录的不断增、删、改,会导致大量的指针链和存储垃圾,降低数据库存储空间的利用率和数据的存取效率,使数据库的性能下降。因此需要进行数据库的重组。数据库管理系统一般都提供重组用的实用程序,按照原设计要求重新安排记录的存储位置,回收垃圾,减少指针链,调整数据区和溢出区等等。数据库的重组不改变原设计的数据逻辑结构和物理结构。当数据库反映的现实世界发生了变化,例如增加了新的应用或实体,原设计不能很好地满足新的需求,就重构数据库。部分修改原数据库的模式或内模式称为数据库的重构,例如增加新的数据项、增加或删除索引等等。数据库管理系统一般也提供了修改数据库结构的功能。数据库的重构的程度是有限的,只能作部分的修改或调整。
(1)数据不长期保存 (2)没有软件系统对数据进行管理 (3)基本上没有文件概念,一组数据就对应一个程序
(1)数据可以长期保存在外存储设备上 (2)有数据管理软件------文件系统 (3)文件的逻辑结构和物理结构之间有一定的区别 (4)文件还是基本上对应于一个或几个应用程序 (5)数据独立性不高 (6)数据冗余度大,浪费存储空间
实体------客观存在并可相互区分的事物。一个实体可以是物理存在的人、事、物,也可以是抽象的概念。
联系------实体之间的相互关系。联系可以分为三种: 一对一联系(1:1)。如果实体集A中的任一个实体至多与实体集B中的一个实体存在联系,反之亦然,则称实体集A与实体集B之间存在一对一联系,记为1:1。 一对多联系(1:n)。如果实体集A中的任一个实体,可以与实体集B中的多个实体存在联系,而实体集B中的每一个实体,至多可以与实体集A中的一个实体相联系,则称实体集A与实体集B存在一对多的联系。记为1:n。 多对多联系(m:n)。如果实体集A中的任一个实体,可以与实体集B中的多个实体存在联系,而实体集B中的每一个实体,也可以与实体集A中的多个实体存在联系,则称实体集A与实体集B存在多对多联系。记为m:n。
属性------实体或联系所具有的某一特性。
数据库系统软件包括数据库管理系统、非数据库管理系统软件和集成数据库管理软件等三大类。 数据库管理系统:处理所有用户对数据库存取请求的软件系统。数据库管理系统允许用户使用一种特殊的语言——数据描述语言。 非数据库管理系统软件。包括操作系统、程序设计语言及其编译系统、数据通信系统以及各种应用程序等。 集成数据库管理软件。辅助或配合数据库管理系统工作的功能部件,是在数据库管理系统上再开发的。有自动报表生成程序、表处理程序、数据库应用开发工具、数据库辅助设计工具、数据库测试工具、数据转换设施等。
应用程序员。负责设计应用系统的程序模块对数据库进行操作。 数据库系统用户包括数据处理人员和非数据处理人员。具体分为以下几类: 应用程序员。负责设计应用系统的程序模块对数据库进行操作。 系统分析员。安装数据库管理系统,调整数据库管理系统与操作系统及其他部件的接口,建立维护数据库管理系统及相关软件的工具,平衡用户之间的资源,进行系统能力规划、系统性能监视与调整等。 数据库管理员(DBA)。支持数据库系统的专业技术人员。执行组织数据库的计划、设计、建立、运行监视、维护以及重开发的全部技术性工作,包括对最终用户的数据库使用技术培训。 计算机操作员。保持系统的联机运行,确定系统问题,执行数据库重组织、后备与故障后的恢复过程、运行日志的管理以及与用户团体交换信息。
CPU。在数据处理中,计算机的运算速度在很大程度上影响了程序运行的时间。 通道。数据检索的速度除了与计算机本身的运算数据有关之外,还有一个更主要的因素就是输入输出操作所占的时间。因为在成千上万条记录中要查找某一数据往往需要多次输入输出操作,高通道能力能够加快输入输出的速度。 内存。数据处理对内存容量的要求要比数据计算的要求大得多。 外存。数据以及用于维护、恢复的副本、日志等都需要存放在外存上。
局部结构的范围划分应遵循划分自然、易于管理、界面清晰、大小适中的原则。可以依据系统的用户进行自然划分,也可以按照数据库提供的服务(应用)分类。 实体、属性和联系之间并无形式上截然区分的界限。在划分时应依据用户的信息处理需求,按照自然习惯确定,注意避免冗余。一个局部结构对一个对象只取一种抽象形式,即一个对象不能既是实体又是联系。一般从信息需求和局部范围定义出发,确定每一个实体类。再依据需求分析,分析局部结构中任何两个实体类是否存在联系及其相应的联系类型,分析其它联系(实体内、多实体间和两实体间多种联系),识别、消除冗余联系,并对联系命名。最后确定属性并将属性分配到所有相关的实体和联系中去。属性应是不可分的,属性与实体间关系为一对多,不同实体间的属性之间应无直接关联关系。
对于中大型系统,由于数据量很大,往往需要设计一个数据输入子系统,用计算机辅助数据的入库工作,以提高输入的效率和质量。 该输入子系统的主要功能是输入、抽取、检验、分类、转换和综合原始数据,最终把数据组织成符合数据库结构的形式。如果数据库是在旧的文件系统或数据库系统的基础之上设计的,则数据输入子系统只需完成数据转换、数据综合两项工作,直接将老系统中的数据转换成新系统中需要的数据格式。 为了保证数据库能及时加载,输入数据子系统的设计应与数据库物理设计工作并行开展。在数据库加载过程中必须高度重视数据的检验工作,保证数据的正确性,防止“垃圾进垃圾出”。