2024-07-11  2024-07-11    29395 字  59 分钟

数据库原理

数据库原理

********************************************  基本概念   **********************************************

一、数据库系统基本概念

    1、信息:信息是客观存在的,是对“现实世界存在的事物”的“运动状态”和“特征”的描述。

    2、数据:数据是用来记录信息的可识别的符号(描述信息的符号记录),是信息的具体表现形式之一。

    3、数据和信息的联系:数据是信息的符号表示或载体。信息是数据的内涵,是对数据语义的解释。

    4、数据库:Database,简称DB。 
    --指长期存储在计算机中的、有组织的、可共享的数据集合。
        特征:
            * 数据按照一定的数据模型组织、描述和存储 (结构化)。
            * 可以被各种用户共享 (可共享)。
            * 数据冗余度小 (冗余度小)。
            * 数据易扩展 (易扩展)。
            * 数据独立性较高 (独立性高)。

        数据库模式
        --数据库中全体数据的逻辑结构和特征的描述,分为外模式、逻辑模式、内模式。

    5、数据库管理系统:Database Management System,简称DBMS
    --是位于 用户 和 操作系统 之间的一层 数据管理软件。

        作用:
            * 能够科学的组织和存储数据
            * 能够高效的获取和维护数据
            
        主要功能:
            * 数据定义:提供数据定义语言DDL,可用于定义数据库中的数据对象。
            * 数据操纵:提供数据操纵语言DML,用于实现对数据对象的基本操作(增删改查)
            * 数据库的建立与维护:
                提供实用的程序,完成 数据库数据 的"批量装入"、"数据库转储"、"介质故障修复"、数据库
                的 "重组织" 和 "性能监控"等。
            * 数据库的运行管理:
                保证数据的"安全性"、"完整性"、多用户对数据库的"并发使用"、发生故障后的"系统恢复"。


    6、数据库系统:Database System,简称DBS。
    --指在计算机系统中引入数据库后的系统构成。
        包括:
            * 数据库
            * 数据库管理系统
            * 应用系统(及其开发工具)
            * 相关人员(用户、数据库管理员、应用系统开发人员等)



二、数据管理技术的产生与发展

    1、人工管理阶段
        时期:
            20世纪40年代中---50年代中
        特点:
            * 数据的管理者:应用程序,数据 不保存
            * 数据面向的对象:某一应用程序
            * 数据的共享程度:不共享、冗余度极大
            * 数据的独立性:不独立,完全依赖于程序
            * 数据的结构化:无结构
            * 数据控制能力:应用程序自己控制

    2、文件系统阶段
        时期:
            20世纪50年代末--60年代中
        特点:
            * 数据的管理者:文件系统,数据可长期保存
            * 数据面向的对象:某一应用程序
            * 数据的共享程度:共享性差、冗余度大
            * 数据的结构化:记录内有结构, 整体无结构
            * 数据的独立性:独立性差,数据的逻辑结构改变必须修改应用程序
            * 数据控制能力:应用程序自己控制

    3、数据库系统阶段
        时期:
            20世纪60年代末至今
        特点:
            * 数据的 管理者: :DBMS
            * 数据 面向的对象 :现实世界
            * 数据的 共享程度 :共享性高
                - 降低数据的冗余度,节省存储空间
                - 避免数据间的不一致性
                - 使系统易于扩充
            * 数据的 独立性 :高度的物理独立性和一定的逻辑独立性
            * 数据的 结构化 :整体结构化
            * 数据的结构用数据模型描述,无需程序定义和解释、数据可以更改长度
            * 数据的最小存取单位:数据项
            ̶* 数据 控制能力 :由DBMS控制

    4 、数据库系统的特点(使用数据库系统的好处)

        * 整体数据结构化:
            在数据库系统中,数据记录的结构和数据记录之间是具有联系的,且这些联系由数据库管理系统
            进行维护,从而减轻了程序员的工作量,提高了工作效率。

        * 数据的共享性高、冗余度低且易扩充:
            多个用户、多个应用可以同时存取数据库中的数据,用户可以用各种方式通过接口使用数据库中的
            数据。同时,数据库通过实现数据共享大大减少了数据冗余,还能够避免数据之间的不相容性和不
            一致性。(数据的不一致性:指同一数据不同副本的值不一样)

        * 数据独立性高:
            数据独立性包括数据的 物理独立性 和 逻辑独立性,即用户的应用程序与数据库中数据的物理存
            储 和数据的 逻辑结构 均相互独立。

        * 数据由数据库管理系统 统一管理和控制:
            利用数据库可对数据进行集中控制和管理,并通过数据模型表示各种数据的组织及数据间的联系
            同时数据库管理系统提供了以下几个方面的数据控制功能,以解决数据共享带来的安全隐患。

                - 数据的安全性保护:
                    保护数据以防止不合法使用造成的数据泄密和破坏;
                - 数据的完整性检查:
                    保证数据的正确性、有效性和相容性(数据中的相容性是指表示同一事实的两个数据应相同,
                    或者满足某一约束关系的一组数据不应发生互斥);
                - 并发控制:
                    使在同一周期内,允许对数据实现多路存取,又能防止用户之间的不正常交互作用(例如,
                    当多个用户的并发进程同时存取、修改数据库时,可能会发生相互干扰而得到错误的结果或
                    使得数据库的完整性遭到破坏);
                - 数据库恢复:
                    数据库管理系统能及时发现故障,并将数据库从错误状态恢复到某一已知的正确状态(亦称为
                    完整状态或一致状态)。

        * 数据库系统和文件系统
            - 操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统

            * 联系和区别:

                其联系在于:
                  (1)都是对数据进行 组织和管理 的技术。
                  (2)均由数据管理软件管理数据,程序与数据之间用存取方法进行转换。
                  (3)数据库系统是在文件系统的基础上发展而来的。

                其区别在于:
                  (1)文件系统用文件将数据长期保存在外存上,数据库系统用数据库统一存储数据。(存储位置)
                  (2)文件系统中的 程序和数据有一定的联系,数据库系统中的 程序和数据分离。(数据独立性)
                  (3)文件系统用操作系统中的存取方法对数据进行管理,数据库系统用DBMS统一管理和控制数据。(数据管理)
                  (4)文件系统实现以文件为单位的数据共享,数据库系统实现以记录和字段为单位的数据共享。(共享程度)


            * 并不是说数据库系统一定优于文件系统

                - 适合于文件系统不适合数据库系统:
                    数据的备份、软件或应用程序使用过程中的临时数据存储一般使用文件比较合适。早期的功能比较
                    简单,比较固定的应用系统也适用文件系统。
                - 适合于数据库系统不适合文件系统:
                    几乎所有企业或部门的信息系统都以数据库系统为基础,都是用数据库。如一个工厂的管理系统。


三、数据模型
    --简单来说,数据模型是对现实世界中 数据特征的抽象。
        它描述了 数据、数据之间的联系、数据上的操作和数据的完整性约束。
        在数据库中用 数据模型 这个工具来抽象、表示和处理现实世界中的数据和信息。
        
    1、数据模型应满足三方面要求:
        * 能比较真实地模拟现实世界
        * 容易为人所理解
        * 便于在计算机上实现

    2、数据模型的分类:

        * 概念模型
            --从现实世界的客观对象中抽象出的某种 信息结构,它不依赖于计算机系统,也不是某种DBMS支持
                的数据模型,仅仅是概念级的模型,称为概念模型。(从用户的观点出发的。 eg.E-R图)

            * 解释:
                概念模型用于信息世界的建模,是 现实世界 到 信息世界 的第一层抽象。为了把现实世界中的
                具体事物抽象、组织为某一数据库管理系统支持的 数据模型 ,人们常常首先将现实世界抽象
                为信息世界,然后将信息世界转换为机器世界。. 也就是说,首先把现实世界中的客观对象抽
                象为某一种信息结构,这种信息结构并不依赖于具体的计算机系统,不是某一个数据库管理系
                统(DBMS)支持的数据模型,而是概念级的模型,称为概念模型。.

            * 概念模型中的一些术语:
                - 实体:
                    客观存在并可相互区别的事物。
                - 实体型:
                    用实体名及其 属性名集合 来抽象和刻画 同类实体,称为实体型。
                    (具有相同属性的实体必然具有共同的特征和性质。如 student(name,age,sex) )
                - 实体集:
                    同一类型实体的集合叫做实体集
                - 属性:
                    实体所具有的某一特性叫做这个实体的属性。
                - 码:
                    唯一标识实体的属性叫做码。
                - 联系:
                    * 联系(Relationship)表示一个或多个实体之间的 关联关系
                    * 联系集(Relationship Set)是指同一类联系构成 的集合
                    * 将联系、联系集等统称为联系。

                    * 联系的元数:
                    -- 一个联系涉及的实体集的个数叫做联系的元数或度数(Degree)
                        * 分类:
                            • 一元联系(递归联系):同一个实体集内部实体之间的联系
                            • 二元联系: 两个不同实体集实体之间的联系
                            • 多元联系: 多个不同实体集实体之间的联系            
                        * 二元联系的类型:(设有两个实体集E1、E2)
                            * 一对一的联系: (1:1)  对于E1中的一个实体来说,E2中最多存在一个实体与其对应
                                对于E2中的一个实体来说,E1中最多存在一个实体与其对应
                            * 一对多的联系: (1:n)  E1中的一个实体可以与E2中的多个实体相对应,E2中的一个
                                实体最多与一个E1中的实体相对应。
                            * 多对多的联系: (m:n)  E1中的一个实体可以与E2中的多个实体相对应,E2中的一个
                                实体与E1中的多个实体相对应。

        * 逻辑模型
        --描述了数据库系统中 所有实体、实体的属性以及实体间的联系。反映了数据之间的逻辑结构。
            (按照计算机系统的观点进行数据建模,用于DBMS的实现)
            反映的是系统分析设计人员对数据存储的观点,是对概念数据模型进一步的分解和细化。
            逻辑模型不关心数据在物理存储上的存储结构,只关心数据之间的逻辑关系、

            * 关系模型: 见307行的《关系数据库》章节
            * 半结构化的数据模型
                ✓ 层次模型:类似树的结构
                ✓ 网状模型:类似图的结构

                ✓ XML、JSON、. . . 
                 

        * 物理模型
        --描述数据在计算机硬件上的存储结构。(从计算机硬件角度出发)

        注意: 
            这些数据模型的根本区别在于 数据结构 不同


    3、数据模型的三要素:
        * 数据结构
            是所研究的对象类型的集合,用于描述数据库的 组成对象以及对象之间的联系。
            (描述 数据模型中有哪些对象,这些对象之间有什么联系)
            (关系模型只有一种数据结构--关系)
        * 数据操作
            是指对 数据库中各种对象(型)的实例(值)允许进行的操作的集合,包括 操作 及有关的操作规则,
            用于描述数据的 动态特征。
            (定义 我们能对数据模型中各对象的实例进行哪些操作)
        * 数据的约束条件
            是一组完整性规则的集合。
            完整性规则是 给定的数据模型中 数据及其联系 所具有的制约和依存规则,用以限定符合数据模型的
            数据库状态以及状态的变化,以保证数据的正确、有效、相容。
            (数据模型中的 数据及联系应该满足哪些约束条件)


四、数据库系统的体系结构

    1、三级模式两级映像

        三级模式:

            * 外模式:也称子模式或用户模式。
            --是 数据库用户使用的局部数据的 逻辑结构和特征 的描述。
                特点:
                    * 逻辑模式和外模式的关系:一对多
                    * 外模式和应用之间的关系:一对多
                外模式的作用:
                    * 保证每个用户只能访问和看到所对应外模式中的数据。
                    * 是保证数据独立性的一个有力措施。

            * 逻辑模式:也称模式。
            --是 数据库中全体数据的 逻辑结构和特征 的描述,是综合了所有用户需求的公共数据视图。
                特点:
                    * 与数据的物理存储细节和硬件环境无关。
                    * 与具体的应用程序、开发工具、高级程序设计语言无关。
                逻辑模式定义的内容:
                    * 数据的逻辑结构(数据项名、类型、取值范围等)
                    * 数据之间的联系
                    * 数据有关的安全性、完整性要求

            * 内模式:也称存储模式。
            --是数据 物理结构和存储方式 的描述、是数据在数据库内部的表现形式。
                包括:
                    * 记录的存储方式
                    * 索引的组织方式
                    * 数据是否压缩存储
                    * 数据是否加密
                    * 数据数据存储记录结构的规定
                注意:
                    * 一个数据库只有一个内模式


        两级映像:
            * 外模式/逻辑模式映像:
            --定义外模式与逻辑模式之间的对应关系。
                * 每一个外模式都对应一个外模式/模式映象
                * 映象定义通常包含在各自外模式的描述中

            * 逻辑模式/内模式映像:
            -- 逻辑模式/内模式映象定义了数据 全局逻辑结构与存储结构之间的对应关系。
                * 数据库中模式/内模式映象是 唯一 的
                * 该映象定义通常包含在逻辑模式描述中


五、数据独立性:

    1、逻辑独立性:(也叫数据于程序的逻辑独立性)
    --指用户的应用程序与数据库的逻辑结构是相互独立的。数据的逻辑结构改变了,应用程序也可以不变。

        说明:
            外模式/模式映象保证了数据的 逻辑独立性
                * 当模式改变时,数据库管理员修改有关的外模式/模式映象,使外模式保持不变
                * 应用程序是依据数据的外模式编写的,从而应用程序不必修改,保证了数据与程
                序的逻辑独立性 。

    2、物理独立性:(也叫数据于程序的物理独立性)
    --指用户的应用程序与存储在磁盘上的数据库中数据是相互独立的。当数据的物理存储改变了,应用程序不用改变。

        说明:
            模式/内模式映象的用途是保证数据的物理独立性
                * 当数据库的存储结构改变了 ( 例如选用了另一种存储结构), 数据库管理员修改
                    模式/内模式映象使模式保持不变。
                * 应用程序不受物理存储方式的影响, 保证了数据与程序的物理独立性。





*******************************************  关系数据库  **********************************************
---关系模型

一、关系的数据结构
    * 关系:(详解见: https://www.cnblogs.com/labixiaohei/p/12105453.html)
    --现实世界中的实体以及实体之间的联系可用关系表示。(对应于实体)

    * 关系模型中 数据的逻辑结构:二维表
    --从用户来看,关系模型中数据的逻辑结构就是一张二维表。

    * 关系模型的基础:集合代数
    --术语介绍:
    
        * 域:
        --具有相同数据类型的值的集合。
            eg. 整数、实数、{'男','女'}等等。

        * 笛卡尔积: 
        --给定一组域D1,D2,,… Dn 
                – 这些域可以完全不同
                – 也可以部分或全部相同
            则D1 ,D2 ,… ,Dn 的笛卡尔积为:
            D1 × D2 × … × Dn = {(d1 , d2 , … , dn )|di ∈ Di ,i=1, 2, … , n}
                – 所有域的所有取值的一个组合
                – 结果中不能有重复的元组(即行)

        * 关系:
        --D1 × D2 × … ×Dn 的子集叫作在域D1 , D2 , … , Dn 上的关系,表示为:
            R(D1 ,D2 ,… ,Dn)
                R : 关系名
                n : 关系的 目 或 度( (Degree) )
                    当n=1时 时 , 称该关系为 单元关系(Unary relation)
                    当n=2时 时 , 称该关系为 二元关系(Binary relation)
            关系的表示:
                * 关系是一个二维表,表的每一行对应一个元组,每一列对应一个域。
                * 关系中不同列可以对应相同的域,为了加以区分,对每列起一个名字,称为属性
            关系的分类:
                * 基本关系:实际存在的表,是实际存储数据的逻辑表示。
                * 查询表:查询结果对应的表,并不存储在磁盘上。
                * 视图:由基本表或其他视图导出的表,是虚表。
            关系的性质:
                * 行的顺序可交换,列的顺序也可交换
                * 每一列中的分量是同一类型的数据,来自同一个域
                * 不同的列可以取自同一个域,但他们的属性名必须不同
                * 属性必须取原子值,即一个属性是一列,不能有一个大属性下面有两个小属性

        * 码:
        --有一个或多个属性组成。
            ✓ 候选码 (Candidate Key): 在关系中能唯一标识元组的属性或属性集
                * 注意:
                    - 一个关系可以有多个候选码
                    - 候选码可以是多个属性的组合
            ✓ 主属性 (Prime Attribute): 候选码的各个属性
                * 注意:
                    - 候选码的每个属性都是主属性
            ✓ 主码 (Primary Key): 用户选择的、作元组标识的候选码
                * 注意:
                    - 一个关系必须有一个主码
                    - 一个关系最多有一个主码
                    - 主码不能取空值
            ✓ 全码 (All- - key): 关系的所有属性是这个关系的候选码
            ✓ 外码 (Foreign Key):如果一个关系R 中的一个属性F 对应着另一关系S的 的 主码K
                那么F 在关系R 中称为 外码。其中S称为被参照表,R称为参照表。
                * 注意:
                    – 关系R 和S 可以是同一个关系
                    – 被参照关系S 的主码K 和参照关系的外码F 必须定义在同一个( 或一组 ) 域上
                    – 外码并不一定要与相应的主码同名
                    – 当外码与相应的主码属于不同关系时 , 往往取相同的名字 ,以便于识别

        * 关系模式:
        -- 关系模式是对关系的描述,关系模式是型、关系是具体的值。(对应于实体型)

            eg. 用关系表示学生这个实体,则:    
                关系模式:学生( 学号, 姓名 , 年龄, 性别, 籍贯)
                关系:具体的每个学生的信息
            * 表示方法:
             关系模式通常可以记为
                R (U) 或 R (A 1 ,A 2 , ,… ,A n )
                    - R : 关系名
                    - A1,A2 ,… ,An : 属性名
            * 关系和关系模式的区别:
                * 关系模式是对关系的描述。是静态的,稳定的
                * 关系是关系模式在某一时刻的状态或内容。是动态的,随时间不断变化的。

        * 关系数据库:
        --在一个给定的应用领域中,用来表示 所有实体及实体之间联系的 关系的集合 构成一个关系数据库。
            例: : 
                教学管理数据库中有四个关系 :
                教师关系T ,课程关系C ,学生关系S ,选课关系SC
                * 关系数据库模式 是关系数据库的型,是对关系数据库的描述
                – 例: : 教学管理数据库 中有四个 关系模式 :
                    T(TID,TNAME,TITLE)
                    C(CID,CNAME,TID)
                    S(SID,SNAME,AGE,SEX)
                    SC(SID,CID,SCORE)
            * 关系数据库的型:
                关系数据库的型也称为关系数据库的模式,是对关系数据库的描述。
                (包括若干域的定义以及在这些域上定义的若干关系模式)
            * 关系数据库的值:
                关系数据库的值是这些关系模式在某一时刻的取值,通常称为关系数据库。

二、关系操作:
    1、常用的关系操作:
        查询、插入、删除、修改
    2、关系操作的特点:
        集合操作方式,即操作的对象和结果都是集合。
    3、关系数据语言的种类:
        * 关系代数语言(早期的,抽象的)
        * 关系演算语言(早期的,抽象的)
        * SQL语言:具有两者双重特点的语言,是现在最流行的语言之一。
    4、关系数据语言的特点:
        * 是一种高度非过程化的语言
        * 能够嵌入到高级语言中使用

三、完整性约束:
    1、完整性规则:
    --关系的完整性规则是指对关系的某种约束条件,包括三类:
        * 实体完整性:
            - 主码唯一
            - 主属性不能取空值
        * 参照完整性:
            - 外码要么取空值,要么取被参照表中某个元组的主码值
        * 自定义完整性:
            - 指用户定义的完整性 是针对某一具体关系数据库的约束条件,反映了某一具体应用所涉及的数据
                必须满足的语义要求。(如: 规定 studen.sex 只能从 {"男","女"} 中取值 )
            - 关系模型 应提供定义和检验这类完整性的机制 , 以便用统一的系统的方法处理它们 , 而不要
                由应用程序承担这一功能。

    2、完整性约束的作用
        保证数据库中数据的正确性,防止不符合规范的数据进入数据库。
            eg. SC以Sno为外键,当违反参照完整性,如插入Sno不存在的学生信息,这将导致数据库中的数据无意义。

四、关系代数的定义:
    --是一种抽象的数据查询语言,用对关系的运算来表达查询。
        * 运算对象和运算结果:关系
        * 运算符:四类
            1、传统的集合运算符
                * 并 "∪" :R ∪ S ,结果由R或S中的所有元组组成
                * 差 "-" :R- S , 结果 由属于R 而不属于S 的所有元组组成
                * 交 "∩" :R ∩ S , 结果由即属于R又属于S的元组构成
                注意:
                    – R 和 S的属性个数必须相同
                    – 对应属性必须取自同一个域
            2、专门 的关系运算符
                * 投影 π :从R中选择出若干属性列组成新的关系
                    π L (R)
                        * L 为R 中的属性列表
                        * 结果为只包含R中某些列的新的关系
                        * 结果要去掉重复元组
                * 选择 σ :在关系R 中选择满足给定条件的各个元组
                    σ C (R)
                        * C :选择条件,是一个逻辑表达式
                        * 结果为只包含R中  某些元组的新的关系
                * 笛卡尔积 x :
                    假设:
                    R 关系:n 个属性,k1 个元组
                    S 关系:m 个属性,k2 个元组
                    则 R × S 结果:
                        * 将R 中的每个元组t1 和S 中的每个元组t2 配对连接
                        * 列数:n+m
                            * 前n 列是关系R 的一个元组t1
                            * 后m 列是关系S 的一个元组t2
                        * 行数: :k1 ×k2
                        * 当R 和S 中有重名属性A 时,则采用R.A 和S.A 
                * 连接 ⋈ :
                    * 连接也称为θ 连接
                        R  ⋈  S 
                        AθB   
                            * A 和 B :分别为R 和S 上度数相等(即属性的个数相等)且可比的属性组
                            * θ :比较运算符
                        – 连接运算从 从R 和S的 的 笛卡尔积R ×S 中选取(R 关系)在A 属性组上的
                        值与(S 关系)在B 属性组上值满足比较条件的元组

                    * 等值连接:
                        * θ 为 = 的连接称为等值连接
                        * 相当于从关系R与S的笛卡尔积中选取A 、B 属性值相等的那些元组
                    * 自然连接:
                    --自然连接是在公共属性(组)上进行的 等值连接
                        注意:
                            – 两个关系中必须具有公共属性(组)
                            – 在结果中把重复的属性列去掉
                    * 自然连接和等值连接的异同点
                        - 相同点:都是属性值是否相等进行连接。
                        - 不同点:自然连接在相同属性值上进行相等比较并投影删除相同的属性;
                            等值连接并不要求在相同的属性上进行相等比较,也不删除相同的属性。

                * 除 ÷ :
                --设关系R除以关系S的结果为关系T,那么:
                    - T中的属性等于R-S的属性
                    - T中元组和S中元组的组合在R中

                    * 注意:
                        - S中的属性如果比R中的多,结果为空集  (也有定义说 S的属性必须是R的真子集才能除)
                        - T × S ∈ R  (即 T和S的笛卡尔积中的元组都是R中的元组 )

                * 重命名 ρ :
                    ρ S(A1,A2 ... An)(R)
                    --将关系R重命名为S,并将R中的属性名重命名为A1,A2 ... An
                        注意:
                            * S可以和R相同
                            * A1,A2 ... An可以和原属性相同
            3、比较符 运算符 
                "<"   "<="   ">"   ">="   "="   "<"   ">"
            4、逻辑运算符
                "﹁"   "∧"   "∨"
            5、关系运算符的优先级:(从上到下,优先级依次递减)
                * 括号
                * 单目运算符优先级最高--- select, project
                * 笛卡尔积和连接运算符
                * 交
                * 并和差




********************************************  SQL、DDL、DCL、DML  ***************************************

一、SQL语言:
    --即,结构化查询语言(Structured Query Language)

    * SQL语言的特点:
        ⒈ 综合统一
        ̶- SQL集 数据定义语言(DDL),数据操纵语言(DML),数据库控制语言(DCL)语言的功能于一体,语言风格统一,
            能独立完成数据库周期中的全部活动。

        2. 高度非过程化
            - 用户只需提出“做什么”,而不必指明“怎么做”
            - 存取路径的选择以及SQL 语句的操作过程由系统自动完成。

        3. 面向集合的操作方式
            - 操作对象、查找结果可以是元组的集合。
            - 一次插入、删除、更新操作的对象可以是元组的集合

        4. 同一种语法结构提供两种使用方式
            - 自含式语言
            - 嵌入式语言

        5. 语言简捷,易学易用
            - 3 大类,11 个命令词

            类     别             动     词
            数据定义DDL         CREATE DROP ALTER
            数据操纵DML         SELECT INSERT UPDATE DELETE
            数据控制DCL         GRANT REVOKE

二、数据定义语言 DDL
    1、SQL的数据定义语言:

    操作对象              操   作   方   式
    -            创     建       删     除         修    改
    模式        CREATE SCHEMA    RDROP SCHEMA
    表          CREATE TABLE     DROP TABLE       ALTER TABLE
    视图        CREATE VIEW      DROP VIEW
    索引        CREATE INDEX     DROP INDEX       ALTER INDEX


        **  **  **  说明:
            以下的语句中, 
            <>表示内容必须写
            []表示内容可选择一部分写,或不写

    * DDL:

        * 预备知识:

            * 常用的数据类型

                * 第一大类: 整数 数据
                    – bigint: 以8 个字节来存储正负数, 范围:-2^63 到 到 2^63 -1
                    – int: 以4 个字节来存储正负数,范围:-2^31 到 到 2^31 -1
                    – smallint: 以2 个字节来存储正负数.范围:-2^15 到 到 2^15 -1
                    – tinyint: 是最小的整数类型, 存储正整数,仅用1 字节, 范围:0 至2^8 -1
                    – bit: 值只能是0 或1 ,当输入0 以外的其他值时, 系统 均认为是1
                * 第二大类: 精确数值 数据
                    – decimal: 用来存储从-10^38 +1 到10^38 -1 的固定精度和范围的数值型数据
                        • 必须指定范围和 精度:decimal (p[,q]) 例 例: :decimal (10,2)
                    – numeric: 和decimal 相同
                * 第三大类: 浮点 数值数据
                    – float: 用8 个字节来存储数据. 最多可为53 位.范围为 为:-1.79E+308 至1.79E+308.
                    – real: 位数为24, 用4个字节、数字范围:-3.04E+38 至3.04E+38
                * 第四大类: 字符串 数据
                    – char: char(n) 固定的长度为 n 个字符的字符串, 不足的长度会用空格补上.
                    – varchar: varchar(n) 可变的最长长度为n 个字符的字符串,尾部的空格会去掉.
                * 第五大类: 日期时间 数据
                    – date: 日期类型
                        • DATE 'yyyy-mm-dd'
                        • Example: DATE '2004-09-30'
                    – time: 时间类型
                        • TIME 'hh:mm:ss'
                        • Example: TIME '15:30:02.5'
                    – datetime: 日期时间类型

            * 常用的完整性约束
                – 主码约束: PRIMARY KEY
                – 参照完整性约束: FOREIGN KEY…REFERENCES…
                – 唯一性约束:UNIQUE
                – 非空值约束:NOT NULL
                – 取值约束:CHECK



        * 模式
            - 模式的定义
                create schema <模式名> authorization <用户名>
            - 模式的删除 
                drop schema <模式名> CASCADE 或 RESTRICT
                    CASACADE:级联  表示删除模式时,把该模式种的所有对象全部删除(包括,表,视图等)
                    RESTRICT:限制  如果模式已经定义了下属对象(如,表,视图等),则拒绝该删除语句的执行。

        * 基本表
            - 创建基本表
                create table <表名>
                (
                    <列名>  <数据类型>  <列级完整性约束>
                    <列名>  <数据类型>  <列级完整性约束>
                    ......
                    [表级完整性约束]
                )

            - 修改基本表
                alter table <表名>
                [ add [column] <新列名> <数据类型>[完整性约束] ]
                [ add <表级完整性约束> ]
                [ drop [column] <列名> [CASCADE 或 RESTRICT] ]
                [ drop constrict<完整性约束名> [CASCADE 或 RESTRICT] ]

                alter column <列名> <数据类型>

                    * CASCADE : 级联  自动删除引用了该列的其他对象
                    * RESTRICT : 限制 如果该列被其他对象引用,拒绝删除此列
                    * drop constrict : 删除完整性约束

            - 删除基本表
                drop table <表名> [ CASCADE 或 RESTRICT ]

            - 基本表和视图
                * 什么是基本表?
                    基本表是数据库中真实存在且存储数据的独立的表。

                * 什么是视图?
                    视图是数据库中虚拟的表,并不真实存储数据,只存储数据的定义。
                    视图在概念上与基本表等同,用户可以在基本表那样使用视图,可以在视图上再定义视图。

                * 两者的区别和联系是什么?
                    区别:
                        存储方式不同(基本表,真实存储数据;视图,不存储真实数据,只存储视图的定义)
                        存在形式不同(基本表,真实存在于数据库中;视图,并不真实存在于数据库中,是一张虚拟的表)
                    联系:
                        视图是由一个或者多个基本表导出的

                * 视图的作用:
                
                    1.对机密数据提供一定的保护功能
                        在设计数据库时,可以对不同的用户定义不同的视图,使机密数据不出现在不应该看到这些数据
                        的用户视图上。
                        eg. student 表涉及15个院系的学生信息,可以在上面定义15个视图,每个视图只包含一个院系
                        的学生数据,并且只允许每个院系的主任查询和修改本院系的学生视图。    

                    2.对重构数据库提供 一定的逻辑独立性
                        eg. 数据库重构中,常常将一个表垂直拆分为多个表,例如:
                            将student(Sno,Sname,Ssex,Sage,Sdept)拆为SX(Sno,Sname,Sage)和SY(Sno,Ssex,Sdept)
                            这时,Student表 是SX和SY两个表自然连接的结果。如果建立一个视图Student 如下:

                                CREATE VIEW Student(Sno,Sname,Ssex,Sage,Sdept)
                                AS
                                SELECT SX.Sno,SX.Sname,SY.Ssex,SX.Sage,SY.Sdept
                                FROM SX,SY
                                WHERE SX.Sno = SY.Sno

                            此时,尽管数据库的逻辑结构改变了,从student拆分为了SX和SY,但应用程序不用改变。
                            因为新建立的视图结构和原来的关系完全一样,用户原来的应用程序通过视图仍能查到数据。      

                    3.简化用户的数据查询操作
                        eg. 某些查询需要用到多张表,这时查询语句需要进行多表连接,用户 需要思考如何连接这些表
                            如果先将这些表连接后定义成一个视图,则 以后只需要对这个表进行简单查询就能得到相同
                            的结果。
                    4.让用户从多种角度看待同一个数据
                        eg. 如,企业将 '学历'属性当作招聘的要求,数据分析部门把学历当作一个变量使用。

                    5.适当利用视图可以更清晰的表达查询

                * 视图的更新:
                --视图不实际存储数据,对视图的更新最终会转化成对基本表的更新。
                    注意:并不是所有的视图都可以进行更新,有些视图的更新不能唯一的转化为有意义的基本表的更新。

                    * 行列子集视图:只从单个基本表导出的,去掉基本表中某些行和某些列,但保留了主码的视图。
                        - 行列子集视图是可更新的
                        - 有些视图在理论上是可更新的,有些则在理论上就是不可更新的。

                * 视图的更新:
                    DROP VIEW <视图名> [CASCADE]
                        视图如果没有导出其他视图,则可以直接删除,否则必须加上CASCADE、否则无法删除。
                        加上CASCADE后,将该视图以及该视图导出的其他视图全部删除。

        * 索引
            - 创建索引
                create [unique] [cluster] index <索引名>
                on <表名>( <列名>[<次序>] 
                        <列名>[<次序>] 
                        ......
                        ) 

                    * unique 表示此索引的一个值只对应于一个记录。
                    * cluster 表示建立的索引是聚簇索引。
                    * <次序> 可选 ASC(升序,默认) 或 DESC(降序)
            - 修改索引
                alter index <旧索引名> rename to <新索引名>
            - 删除索引
                drop index <索引名>

    * DML:
        * 数据查询
        * 数据更新
        * 数据修改 
        * 数据删除

    * DCL:
        * 数据授权
        * 权限收回

    * 空值的处理

    * 视图

    * SQL的一些总结:

        * 常用的关键字:
            all / distinct
            all / any
            in / not in
            is null / not is null
            in / exists
            between and
            like / not like     '%' , '_' 和 '\' 的用法
            where / having
            相关子查询 / 不相关子查询
            join / left join / right join / all join
            ASC / DESC

        * select语句的执行顺序:

            1、from 子句组装来自不同数据源的数据;
            2、where 子句基于指定的条件对记录行进行筛选;
            3、group by 子句将数据划分为多个分组;
            4、使用聚集函数进行计算;
            5、having 子句筛选分组;
            6、计算所有的表达式;
            7、select 的字段;
            8、使用 order by 对结果集进行排序。

        * 易混淆的关键词比较:

            - in 和 exists 的区别:
                * A是员工表,B是部门表。下面为查询 所有部门的 所有员工的两种实现方式:
                    select * from A where deptID in(select deptID from B);
                    select * from A where deptID exists(select deptID from B);

                * 分析:
                    --对于用in的查询方式。先执行子查询,即 从B表中查出所有 deptID 、再从子查询结果
                        中拿出一个deptID 与 主查询 A中的deptID 依次比较,将deptID=A.deptID 的记录放
                        入结果表中。 然后取出子查询结果表中的下一条 deptID 、重复上述步骤。
                        (相当于子查询是外层循环,主查询是内层循环)

                    --对于用exists的查询方式,正好与上述过程相反(主查询是外层循环,子查询是内层循环)

                * mysql的优化原则是"小表驱动大表",即应该让数据量大的表作为内层循环。因此
                    - 当主查询表的元组数量多于子查询表的元组数量时,用in的查询效率高
                    - 当主查询表的元组数量少于子查询表的元组数量时,用exists的查询效率高


            - where 和 having 的区别:
            ---where的作用对象是基本表或视图,having的作用对象是分好的组,一般跟在group by 之后。
                * having并不是一定要跟在group by 之后。
                    eg. select a,b,c from tableA where a > 100;
                        select a,b,c from tableA having a > 100;
                        上述两个句子是等价的,都可以(因为select中已经提前筛选出了'a'属性)

                    eg. select b,c from tableA where a > 100;
                        select b,c from tableA having a > 100;
                        上述having会报错(因为select中没有筛选出了'a'属性,having不能对基本表进行操作)

                    eg. select avg(a) as av,b,c 
                        from tableA 
                        where av > 100 
                        group by d;

                        select avg(a) as av,b,c 
                        from tableA
                        group by d
                        having av > 100;
                        上述where将会报错(因为where对基本表进行操作,基本表中没有 'av' 这个属性)


                * where
                    - where在查询结果集返回之前,根据条件进行筛选 然后返回结果集。
                    - where中不能使用聚合函数
                    - where是一个约束声明
                * having
                    - having在查询结果集返回之后,根据条件对结果集的内容进行筛选。
                    - having中可以使用聚集函数
                    - having是一个过滤声明

            - char 和 varchar 的区别:
                * char: 
                    定长字符串,如果插入的字符长度小于定义的长度,用空格补齐
                    存取速度比varchar快得多
                    方便程序的存储和查找
                * varchar:
                    变长字符串,插入的字符长度是多少,就占用多少个字符空间,但是会增加一个字节记录字符串长度
                    存取速度较慢
                    查找不方便

                * char是用空间换时间、varchar用时间换空间



******************************************  数据库的安全性  *********************** ***************

一、数据库的安全性
    --数据库的安全性指 防止由于数据库的不合法使用造成的数据泄露、更改或破坏。
        * 数据库系统的安全保护措施是否有效是数据库系统主要的性能指标之一

    1、数据库中 数据的共享
        * 数据库系统中的数据共享不能是无条件的共享,否则将会导致一系列的安全问题。如泄露国家机密等
        * 数据库中数据的共享 是在DBMS严格统一的控制之下的共享,只允许有合法使用权限的用户访问允许他存取的数据。

    2.数据库的不安全因素
        * 非授权用户对数据库的恶意存取和破坏
        * 数据库中重要或敏感的数据被泄露
        * 安全环境的脆弱性

    3、安全性控制的一般方法

        (1) 用户身份鉴别

            * 静态口令鉴别: 设置口令(密码),输入正确的口令后才能对数据库进行操作。(即,需要先登录数据库管理系统)
            * 动态口令鉴别: 每次登录都需要使用动态产生的新口令。(如、短信验证码登录)
            * 生物特征鉴别: 通过每个生物体所特有的、可测量、识别和验证的稳定的生物特征。(指纹,虹膜等)
            * 智能卡鉴别: 智能卡是一种不可复制的硬件,内置集成电路芯片,具有硬件加密的功能、


        (2) 存取控制

            * 存取控制要达到的目的:
                保证每个用户只能访问到自己有权读取的数据。

            * 存取控制包括:
                - 用户权限定义:
                    必须预先对每个用户定义存取权限,这些定义被编译后存储在数据字典中。被称为授权规则。
                - 合法权限检查:
                    用户提出存取数据库的操作后,数据库管理系统查找数据字典,根据安全规则进行合法权限检查,
                    如果用户的操作请求超出了它的权限,系统将拒绝执行此操作。

            * 用户权限的组成
                数据对象:用户权限的作用对象
                操作类型:用户可以对操作对象进行哪些类型的操作。

                -- 定义用户权限就是 "定义一个用户可以在哪些数据对象上进行哪些类型的操作"。

            * 授权粒度:
            --指能把一个用户的权限对象划分到多详细,它是衡量授权机制是否灵活的一个重要指标。
                * 授权定义中数据对象的粒度越细,即可以定义的数据对象的范围越小,授权子系统就越灵活。

                * 关系数据库中授权的数据对象粒度分为
                    – 数据库
                    – 表
                    – 属性列
                    – 行

            * 自主存取控制方法:
            --用户可以自主的决定将数据的存储权限授予任何人,甚至决定是否 将"授权"的权限授予别人。
                因此,这样的存取控制称为自主存取控制。

                * 授权: 为某个用户 定义存取权限称为授权。
                    - 语法:
                    grant<权限> [ <权限> ]...
                    on <对象类型> <对象名> [ <对象类型> <对象名> ]...
                    to <用户> [ <用户> ]...
                    [ WITH GRANT OPTION ]

                * 收回: 剥夺某用户的 存取权限称为收回。
                    - 语法:
                    revoke<权限> [ <权限> ]...
                    on <对象类型> <对象名> [ <对象类型> <对象名> ]...
                    from <用户> [ <用户> ]...
                    [ CASCADE|RESTRICT ]

            * 数据库角色
            --数据库角色是一组被命名的,与数据库操作相关的权限,角色是权限的集合。

                语法参考数据库课本p146页内容
                - 角色的创建
                - 角色的授权
                - 将一个角色授予其他角色或用户
                - 角色权限的收回

            * 强制存取控制方式
            -- 将DBMS管理的所有实体分为 主体和客体 两类,DBMS为他们的每个实例指派一个敏感度标记。
                主体的敏感度标记叫做 "许可证级别",客体的叫做 "密级" 。
            
                * 主体对客体的存取操作必须遵循以下规则
                    - 当主体的许可证级别 大于等于 客体的密级时,该主体才能读取相应的客体。
                    - 当主体的许可证级别 小于等于 课题的密级时,该主体才能写相应的客体。

                * 强制存取控制是对数据本身进行密级标记,无论数据如何复制,标记和数据都是一个不可分割的整体,
                只有符合密级标记要求的用户才能操纵数据,从而提高了更高的安全性。

        (3) 视图
        --视图机制把要保密的数据对无权存取这些数据的用户隐藏起来,从而自动地对数据提供一定程度的安全保护。
            视图机制更主要的功能在于提供数据独立性,其安全保护功能不太精细,往往远不能达到应用系统的要求。

        (4) 审计
        --审计功能把用户对数据库的操作全部记录下来,放入审计日志(audit log),审计员可以利用审计日志监控数
            据库中的各种行为,重现导致数据库现有状况的一系列事件,找出非法存取数据的人、时间和内容等。

            * 注意:审计功能很费时间和空间,DBMS往往将审计功能作为 可选择开启选项。

            * audit 和 noaudit 语句

        (5) 密码存储
        -- 根据一定的算法,将原始数据(明文)变换为不可直接识别的格式(密文)、
        这样就使得不知道解密算法的人无法获知数据内容。

            * 存储加密
                - 透明加密:当对加密数据进行增删改查时,DBMS自动对数据进行加密解密操作,用户完全感知不到。
                    基于数据库内核的存储加密、解密方法性能较好,安全完备性高。
                - 非透明加密: 通过多个加密函数实现。

            * 传输加密

        (6) 其他安全保护
            * 推理控制:防止用户通过自己能够访问的数据推知更高密级的数据
            * 隐蔽信道:看书上p153的例子


********************************************  数据库的完整性  ****************************************
数据库的完整性 定义:
    数据库的完整性指的是 数据库的 正确性 和相容性
        正确性:数据是符合现实世界语义,反应当前的实际情况的。
            ( eg. 一个人的年龄是 -12岁,显然不正确 )
        相容性:指数据库同一对象在不同关系中的数据是否符合逻辑。
            ( eg. 小明在选课表中没有选 数学课,但是它的成绩表却显示它的数学成绩为100分 显然不相容)


一、实体完整性
    * 内容
        - 主键的取值非空,并且取值唯一
        - 主属性不能为空
    * 违约处理
        每当用户向数据库中插入一条数据,DBMS都会对实体完整性进行检查
        - 判断主码的值是否唯一,如果不唯一,则拒绝插入此记录
        - 判断主属性的值是否为空,如果为空,则拒绝插入此记录

    * 注意:
        由于要检查实体完整性,因此每次插入数据都要对整个表的记录进行扫描,这是一个非常耗时的过程。
        为了解决这个问题,DBMS一般在主码上自动建立一个索引,如B+树索引。这样就可以索引查找本表中
        是否存在待插入的主码值,大大提高了效率。

二、参照完整性
    * 内容
        - 外码的值要么取空值,要么取被参照表中主键的某个值。

    * 违约处理:
    --对参照表和被参照表进行操作时,可能破快参照完整性,因此操作前需要进行检查
        - 当往参照表内插入记录,或修改参照表中的外码的值时,可能破坏参照完整性、
        - 当删除被参照表中的记录,或者修改被参照表中的主码值时,可能破坏参照完整性、

    --当参照完整性被破坏时,DBMS的处理策略
        - 拒绝执行(NO ACTION):
            拒绝该操作的执行,这是默认的策略。

        - 级联操作(CASCADE):
            当删除被参照表中的一个元组,或修改被参照表中的元组导致参照表的数据不一致时,删除参照表中
            所有导致不一致的元组。

            eg. 删除students中学号为001的学生记录,采用级联操作时,SC表中所有学号为001的学生的成绩
            都会被删除。

        - 设置空值法
            当删除被参照表中的一个元组,或修改被参照表中的元组导致参照表的数据不一致时,将参照表中
            所有导致不一致的元组的相关属性设置为空值。

        * 注意: 只有删除或修改被参照表中的元组时,才会用到CASCADE和设置空值法,在参照表中插入元组
        或修改参照表中的外码值时,如果违反参照完整性,则直接拒绝执行。

三、用户自定义的完整性
    * 列值非空(NOT NULL)
    * 列值唯一(UNIQUE)
    * 检查列值是否满足某一表达式(CHECK)
    *   ... ...

四、完整性约束命名子句
    1、给完整性约束命名
        * constrict <完整性约束名> <完整性约束条件>
            eg. constrict name1 NOT NULL;
                constrict name2 CHECK(sage>10);

    2、删除某个完整性约束 
        * drop constrict <完整性约束名>
            eg. drop constrict name1;


断言
触发器


*、数据库的完整性和安全性
    * 完整性:数据库的完整性是指,数据库中数据的正确性、一致性和相容性
    * 安全性:防止用户非法使用数据库造成数据泄露,更改或破坏。
    * 区别和联系
        联系:都时为了保护数据库中的数据,是一个问题的两个方面、
        区别:完整性是防止数据库的合法用户对数据更改时,破坏数据库的一致性;
            安全性旨在防止未经授权的用户访问数据库,对数据库中的数据进行进行恶意破坏和修改。

********************************************  范式  **********************************************

一、关系模式的形式化定义
    1、关系模式由五部分组成
    --R(U,D,DOM,F)
        R: 关系名
        U: 组成该关系的属性名集合
        D: 属性集合中的属性所来自的域
        DOM: 属性向域的映像集合
        F: 属性间数据依赖关系的集合
    
    2、数据依赖
        --"属性值"间的相互关连(主要体现于值的相等与否)的关系叫做 数据依赖 ,它是数据库模式设计的关键。
            * 注意:
                ✓ 数据依赖通过一个关系中 属性间值的相等与否 体现数据间的相互关系
                ✓ 数据依赖是现实世界 属性间相互联系 的抽象
                ✓ 数据依赖是数据内在的性质
                ✓ 数据依赖是语义的体现

        * 数据依赖的分类:
        
            * 函数依赖(Functional Dependency ,简记为FD):
            --设 R(U)是一个属性集U上的关系模式,X和Y是U的子集,若对于R(U)的任意一个可能的关系r满足:
                r中不可能存在两个元组在X上的属性值相等, 而在 Y 上的属性值不等,则称"X函数确定Y"
                或 "Y函数依赖于X" ,记作X→Y。   
                X 称为这个函数依赖的 决定属性集(Determinant)。

                * 说明:
                    1. 函数依赖是指R的所有关系实例均要满足的约束条件
                    2. 函数依赖是 语义范畴的 概念
                        例如  “姓名→ 年龄”这个函数依赖只有在不允许有同名人的条件下成立
                    3. 数据库设计者可以对现实世界作强制的规定
                        例如  设计者可以强行规定不允许同名人出现,因而使函数依赖“姓名→年龄”成立
                    4. 若X→Y ,并且Y→X, 则记为 X↔Y
                    5. 若X→Y ,且Y不函数依赖于X, 则记为 X→Y。

                * 平凡函数依赖 和 非平凡函数依赖
                --在关系模式R(U) 中,对于U 的子集X 和 Y
                    * 如果X→Y ,但Y ∈ X ,则称X→Y是 平凡的函数依赖
                        例 :在关系模式SC(Sno, Cno, Grade) 中
                            非平凡函数依赖 :(Sno, Cno) → Grade
                            平凡函数依赖 :(Sno, Cno) → Sno 或 (Sno, Cno) → Cno
                    * 如果X→Y ,但Y ∉ X ,则称X→Y是 非平凡的函数依赖

                    * 注意: 
                        对于任一关系模式,平凡函数依赖都是必然成立的, 它不反映新的语义。
                                    
                * 完全函数依赖 和 部分函数依赖
                --在关系模式R(U)中
                    * 如果 X→Y ,并对于X的任何一个真子集x,满足x不能函数确定Y, 则称Y完全函数
                        依赖于X,记作 X →f Y。 (f在箭头上面标着)

                        小技巧: (即 如果X函数确定Y , 那么X的任意真子集一定不函数确定Y)

                    * 如果 X→Y ,但 Y 不完全函数依赖于 X ,则称Y 部分函数依赖于X。记作 X →p Y。

                        例 例: 对于关系模式 SC(Sno, Cno, Grade)
                            若:
                            - Grade由Sno和Cno共同确定
                            - Sno不能函数确定Grade ,Cno不能函数确定Grade
                            则:
                            - (Sno, Cno) →f Grade
                            - (Sno, Cno) →p Sno, (Sno, Cno) →p Cno

                * 传递函数依赖
                --在关系模式R(U)中,如果X →f Y ,Y→Z 、X不函数依赖于Y ,则称Z传递函数依赖于X
                    如果Y→X,即X←→Y ,则Z直接依赖于X。      (注:若Y∈X,相当于X→Z)

                        * 例: 
                            在关系Std(Sno, Sdept, Mname) 中,
                            有:Sno → Sdept ,Sdept → Mname
                            则:Mname 传递函数依赖于Sno

                * 码:
                --设K为关系模式R(U,F) 中的属性或属性组合
                    若K →f U ,则K 称为R 的一个 侯选码(Candidate Key)。
                    若关系模式R有多个候选码,则选定其中的一个做为主码(Primary key)。

                    * 补充:
                        * 候选码 能够唯一地标别关系的元组,是关系模式中一组最重要的属性
                        * 主码 又和 外码 一起提供了一个表示关系间联系的手段

            * 多值依赖(Multivalued Dependency ,简记为MVD)

            * 连接依赖

    3、范式
    --关系数据库中的关系必须满足一定的要求,满足不同要求的为不同范式。
    --范式是指 满足某一级别的关系模式 的集合。
        * 分类
            * 第一范式(1NF):
            --如果一个关系数据库的所有属性都是不可再分的基本数据项,则R∈1NF。
                * 第一范式是对关系模式的最基本的要求,不满足第一范式的数据库模式不能称为关系数据库。
                * 但是满足第一范式的关系模式并 不一定是一个好的关系模式。

                * 例: 式 关系模式 SLC(Sno, Sdept, Sloc, Cno, Grade)
                    其中各属性分别为学号,所在系,宿舍楼,课程号和成绩。
                    规定:
                    * 一个学生就属于一个系,每个系的学生住在同一个宿舍楼
                    * 一个学生学的每一门课程都有唯一的成绩。
                    写出所有的函数依赖 :
                        Sno → Sdept ,Sdept → Sloc,(Sno, Cno) → Grade
                        (Sno, Cno) → Sno ,(Sno, Cno) → Sdept
                        (Sno, Cno) → Sloc, (Sno, Cno) → Cno
                    * 分析:
                        - SLC满足第一范式
                        - 非主属性Sdept 和Sloc 部分函数依赖 于码(Sno, Cno)
                        假设 Sno = 95102 , Sdept = IS , Sloc=N 的学生还未选课,因课程号是主属性,因此
                        该学生的信息无法 插入。(诸如此类的问题还有很多)
                    * 结论:
                        仅满足第一范式的关系模式不一定是一个好的关系模式,如果非主属性部分函数依赖于码,
                        很可能存在插入异常、删除异常、数据冗余度大、修改复杂等问题。

            * 第二范式(2NF):
            --如果R∈1NF,且不存在非主属性对码的部分函数依赖,则R∈2NF。
                * 例:SLC(Sno, Sdept, Sloc, Cno, Grade) ∈ 1NF
                将SLC进行拆分得到下面两个关系模式,则:
                    SC(Sno,Cno,Grade)∈ 2NF
                    SL(Sno,Sdept,Sloc)∈ 2NF

                    * 分析:
                        写出所有函数依赖 :
                            Sno→Sdept
                            Sno→Sloc
                            Sdept→Sloc
                        - SL 的码是Sno
                        - Sloc 传递函数依赖于Sno ,即SL 中存在 非主属性对码的传递函数依赖。
                        假设学校调整学生住处时,由于关于每个系的住处信息是重复存储的,修改
                        时必须同时更新该系所有学生的Sloc。(诸如此类的问题还有很多)

                    * 结论:
                        采用 投影分解法 将一个1NF 的关系分解为多个2NF 的关系,可以在一定程度上减轻原1NF 
                        关系中存在的插入异常、删除异常、数据冗余度大、修改复杂等问题。将一个1NF 关系分解
                        为多个 2NF 的关系, 并不能完全消除 关系模式中的各种异常情况和数据冗余。
                
            * 第三范式(3NF):
            --关系模式 R∈1NF ,且不存在非主属性对码的传递函数依赖 ,则称R∈3NF。
                * 例 SL(Sno, Sdept, Sloc) ∈ 2NF
                将关系模式SL进行分解得到SD和DL,则:
                    SD(Sno,Sdept)∈ 3NF
                    DL(Sdept,Sloc)∈ 3NF
                * 分析:
                    采用投影分解法将一个2NF 的关系分解为多个3NF 的关系,可以在一定程度上解决原2NF 
                    关系中存在的插入异常、删除异常、数据冗余度大、修改复杂等问题。将一个2NF 关系分
                    解为多个3NF的关系后,在有些情况下,不能完全消除关系模式中的各种异常情况和数据冗余。

            * BC 范式(BCNF):
            --设关系模式R ∈ 1NF,如果对于R的每个函数依赖X→Y ,若Y不属于X ,则 X 必含有候选码,那么R∈BCNF。 
            --换句话说,在关系模式R 中,如果每一个 决定属性集 都包含候选码,则R∈BCNF。

                * BCNF 的关系模式所具有的 性质:
                    - 所有 非主属性 都完全函数依赖于每个候选码
                    - 所有 主属性 都完全函数依赖于每个不包含它的候选码
                    - 没有任何属性 完全函数依赖于 非码

                * 3NF和BCNF的关系:
                    – 如果关系模式R∈BCNF ,必定有R ∈ 3NF。
                    – 如果R∈3NF,且R 只有一个候选码,则R 必属于BCNF。

                * 总结:
                    如果一个关系数据库中的所有关系模式都属于BCNF ,那么在 函数依赖 范畴内,它已实现了
                    模式的彻底分解,达到了最高的规范化程度,消除了插入异常和删除异常。


            * 第四范式(4NF):
            * 第五范式(5NF):


        * 各个范式之间的联系:
                * 1NF是对关系模式的最基本要求,不满足1NF的关系模式不能被称为关系数据库
                * 2NF在1NF的基础上消除了部分函数依赖,减轻了插入、删除异常等问题。
                * 3NF在1NF的基础上消除了传递函数依赖,进一步减轻了各类异常。(可以证明满足3NF一定满足2NF)
                * BCNF消除了"主属性对候选键的部分依赖和传递依",在函数依赖范围内实现了彻底分解
                    消除了产生插入异常和删除异常的根源,并将数据冗余减轻到极小的程度。
        * 小技巧:
                某一关系模式R 为第n 范式,可简记为R ∈nNF

        * 各个范式之间的关系:
            1NF ⊂ 2NF ⊂ 3NF ⊂ BCNF ⊂ 4NF ⊂ 5NF 

    4、关系模式的规范化
        * 前言:
            关系数据库的规范化理论是数据库逻辑设计的工具,一个关系只要其分量都是不可分的数据项,它就是规范化的关系,
            但这只是最基本的规范化。规范化程度可以有6 个不同的级别,即6个范式。
            规范化程度过低的关系不一定能够很好地描述现实世界,可能会存在 插入异常、删除异常、修改复杂、数据冗余等问
            题,解决方法就是对其进行规范化,转换成高级范式。 一个低一级范式的关系模式,通过模式分解可以转换为若干个
            高一级范式的关系模式集合,这种过程就叫 关系模式的规范化。

        * 关系模式规范化的步骤:
            1NF -> 2NF:消除 非主属性 对码的部分函数依赖,从而达到2NF
            2NF -> 3NF:消除 非主属性 对码的传递函数依赖,从而达到3NF
            3NF -> BCNF:消除 主属性 对码的 部分函数依赖 和 传递函数依赖 从而到达 BCNF
            BCNF -> 4NF:消除 平凡且非函数依赖的 多值依赖,从而到达4NF
            4NF -> 5NF:消除不是由 候选码 所蕴含的 连接依赖,从而到达5NF
            * 注意:
                - 不能说规范化程度越高的关系模式就越好
                - 在设计数据库模式结构时,必须对现实世界的实际情况和用户应用需求作进一步分析,确定一个合适的、
                    能够反映现实世界的模式。
                - 关系模式的规范化可以在上述任何一步终止

        * 关系模式的分解:
            --将一个关系模式R(U,F) 分解为若干个关系模式R1(U1,F1),R2(U2,F2) ,… ,Rn(Un,Fn)
                ✓ 其中U = U1 ∪ U2 ∪ … ∪ Un ,且不存在Ui ⊆ Uj ,Fi 为 F 在Ui上的投影。
                ✓ 上述分解意味着相应地将存储在一个二维表t 中的数据分散到若干个二维表t1 ,t2 ,… ,tn 中去
                其中ti 是t 在属性集Ui上的投影。(i=1,2,3...n)

            * 模式分解的 无损连接性(模式分解的第一个要求)
                * 设关系模式R(U,F) 被分解为若干个关系模式R1(U1,F1) ,R2(U2,F2) ,… , ,Rn(Un,Fn)
                ✓ 其中U=U1 ∪U2 ∪… ∪Un ,且不存在Ui ⊆ Uj
                ✓ Fi 为F 在Ui 上的投影

                    * 无损连接性:
                    --若R与R1 、R2 、… 、Rn自然连接的结果相等,则称关系模式R的这个分解具有无损连接性(Lossless join)
                    * 注意:
                        * 只有具有无损连接性的分解才能够 保证不丢失信息
                        * 无损连接性 不一定能解决 插入异常、删除异常、修改复杂、数据冗余等问题

            * 保持原关系中的函数依赖(模式分解的第二个要求)
                *  设关系模式R(U,F) 被分解为若干个关系模式R1(U1,F1) ,R2(U2,F2) ,… ,Rn(Un,Fn)
                ✓ 其中U=U1 ∪U2 ∪… ∪Un ,且不存在Ui ⊆ Uj
                ✓ Fi 为F 在Ui 上的投影

                    * 保持函数依赖的(Preserve dependency):
                    --若F 所逻辑蕴含的函数依赖一定也由分解得到的某个关系模式中的 函数依赖Fi 所逻辑蕴含,
                        则称关系模式R的这个分解是 保持函数依赖的(Preserve dependency )。

        * 关系模式的一个分解与原关系模式等价的充要条件是
            * 分解具有无损连接性
            * 分解保持函数依赖

            * 说明:
                * 如果一个分解具有 无损连接性 ,则它能够保证不丢失信息
                * 如果一个分解保持了 函数依赖 ,则它可以减轻或解决各种异常情况
                * 分解具有无损连接性和分解保持函数依赖是两个互相独立的标准
                    ✓ 具有无损连接性的分解不一定能够保持函数依赖
                    ✓ 同样,保持函数依赖的分解也不一定具有无损连接性

        * 模式分解的算法
            规范化理论提供了一套完整的模式分解算法,按照这套算法可以做到
                – 若要求分解具有无损连接性,那么模式分解一定能够达到4NF
                – 若要求分解保持函数依赖,那么模式分解一定能够达到3NF ,但不一定能够达到BCNF
                – 若要求分解既具有无损连接性,又保持函数依赖,则模式分解一定能够达到3NF



********************************************  数据库设计  ****************************************
一、数据库设计
    1、 数据库设计(Database Design ,简记为 DBD):
    -- 构造最优的数据模型,建立数据库及其应用系统的过程。
        小提示:数据库设计的优劣将直接影响应用系统的质量和运行效果。

    2、数据库设计的步骤:
        * 数据库系统的生存期:
        --规划阶段:
            *  规划的意义:
            --对于数据库系统, 特别是大型数据库系统,规划阶段是十分必要的。规划的好坏将直接影响到整个系统的成功与否。
            * 规划的步骤:
                * 系统调查
                    • 对应用单位作全面的调查,发现其存在的主要问题
                    • 画出 组织层次图 ,以了解企业的组织机构
                * 可行性分析
                    • 从技术、经济、效益、法律等方面对建立数据库系统的可行性进行分析
                    • 写出 可行性分析报告
                    • 组织专家进行讨论其可行性
                * 确定数据库系统的总目标
                    • 对应用单位的工作流程进行优化和制订项目开发计划
                    • 在得到决策部门批准后,就正式进入数据库系统的开发工作

            1 需求分析阶段:
            --进行数据库设计必须首先 准确了解用户的需求,需求分析是整个设计过程的基础,是最困难最耗时的一步。
            (分析用户需要用数据库存储哪些信息,需要对这些信息进行哪些操作,对这些信息的安全性和完整性有什么需求)

                * 需求分析的内容:
                    • 计算机人员(系统分析员)和用户双方共同收集数据库所需要的信息内容和用户对处理的需求。
                    • 以 需求说明书 的形式确定下来,作为以后系统开发的指南和系统验证的依据。
                * 需求分析的步骤:
                    • 分析用户活动,产生 业务流程图
                    • 确定系统范围,产生 系统关联图
                    • 分析用户活动涉及的数据,产生 数据流图
                    • 分析系统数据,产生 数据字典
                * 数据字典:
                    - 组成:
                        包括五部分:    数据项、数据结构、数据流、数据存储、处理过程
                        数据字典里存储了 数据库中所有数据元素的定义。
                    - 作用:
                        可以作为分析阶段的工具,它给数据流程图上的每个成分做出详细说明,供人们查询使用。



            2 概念设计阶段:
            --通过对用户需求进行综合、归纳与抽象,形成一个独立于DBMS的概念模型。(概念设计是整个数据库设计的关键)
            (对用户需求进行综合归纳,抽象出独立于计算机系统,不依赖于DBMS的信息结构,也就是概念模型)

                * 目标:
                    产生反映用户需求的 数据库概念结构,即 概念模型。它具有硬件独立和软件独立的特点。
                * 概念设计的主要步骤:
                    1. 进行数据抽象,设计局部概念模型
                        • 从实际的人、物、事和概念中抽取所关心的 共同特性,忽略非本质的细节,
                            并把这些特性用各种概念加以 精确描述
                        • 概念结构是对现实世界的一种抽象
                    2. 将局部概念模型综合成 全局概念模型
                        • 综合各局部概念结构就可得到反映所有用户需求的全局概念结构
                        • 在综合过程中,主要处理各局部模式对各种对象定义的 冲突( 属性冲突、命名冲突、结构冲突)
                    3. 评审
                        • 消除了所有冲突后,就可把全局结构提交评审
                        • 评审分为用户评审与DBA及应用开发人员评审两部分

                * 概念设计的方法:
                    • 概念设计中最著名的方法就是 实体联系方法(ER 方法)
                    • 概念设计的结果是得到一个与DBMS无关的概念模型。

            3 逻辑设计阶段:
            -- 将概念结构转换为DBMS上支持的数据模型,并对其进行优化。

                * 逻辑设计的目的:
                    把概念设计阶段设计好的 概念模型转换成与选用的具体机器上的DBMS 所支持的数据模型相符合的
                    逻辑结构 (包括数据库逻辑模型和外模型)。
                * 对于逻辑设计而言,应首先选择DBMS ,但往往数据库设计人员没有挑选的余地,都是在指定的DBMS
                    上进行逻辑结构的设计。
                * 逻辑设计的步骤:
                    1、把概念模型转换成逻辑模型
                    2、设计外模型
                    3、设计应用程序与数据库的接口
                    4、评价模型
                    5、修正模型

            4 物理设计阶段:
            --为逻辑数据模型选取一个 最适合应用环境的 物理结构的过程,称为 物理设计。

                * 物理设计的步骤;
                    * 物理结构设计:
                        ⑴ 存储记录结构设计
                        ⑵ 确定数据存放位置
                        ⑶ 存取方法的设计
                    * 约束和具体的程序设计:
                        ⑷ 完整性和安全性考虑
                        ⑸ 程序设计

            5 数据库的实施阶段:
            --设计人员利用DBMS提供的数据库语言及其宿主语言,根据逻辑设计和物理设计的结果建立数据库、编写
                与调试应用程序、并进行试运行。

                * 数据库实现的过程
                    • 用DDL 定义数据库结构
                    • 组织数据入库
                    • 编制与调试应用程序
                    • 数据库试运行

            6 数据库的运行与维护:
            --一个完善的数据库应用系统不可能一蹴而就。因此,在数据库系统运行过程中必须对其不断地评估、调整与修改。
            
                * 对数据库经常性的维护工作主要是由DBA 完成的
                    – 数据库的转储和恢复
                    – 数据库安全性、完整性控制
                    – 数据库性能的监督、分析和改进
                    – 数据库的重组织和重构造
                * 若应用变化太大,已无法通过重构数据库来满足新的需求,或重构数据库的代价太大,
                    则表明现有数据库应用系统的生命周期已经结束,应该重新设计新的数据库系统,开始 
                    新数据库应用系统的生命周期 了。


二、E-R模型 (Entity Relationship Mode)
    1、E-R模型的基本元素
        * 实体(Entity) 是指 数据对象,指应用中可以区别的客观存在的事物。
        * 实体集(Entity Set) 是指同一类实体构成的 集合
            例: 
                实    体       实   体   集
                一个学生         全部学生
                一门课程         全部课程
                一个老师         全部老师

        * 属性(attribute):
            – 实体的某一特性称为 属性(Attribute)
            – 在一个实体中,能够惟一标识实体的属性或属性集 称为“ 实体标识符 ”
            – 一个实体只有一个标识符,没有候选标识符的概念。实体标识符有时也称为 实体的主键
            – 实体若干属性的一组特定值,确定了一个特定的实体

        * 联系(Relationship):
            – 联系( (Relationship )表示一个或多个实体之间的 关联关系
            – 联系集(Relationship Set )是指同一类联系构成 的集合
            – 将联系、联系集等统称为联系 。

            * 联系的元数:
                一个联系涉及的实体集的个数叫做联系的元数或度数(Degree)
                * 分类:
                    • 一元联系(递归联系):同一个实体集内部实体之间的联系
                    • 二元联系: 两个不同实体集实体之间的联系
                    • 多元联系: 多个不同实体集实体之间的联系            
                * 二元联系的类型:(设有两个实体集E1、E2)
                    * 一对一的联系: (1:1)  对于E1中的一个实体来说,E2中最多存在一个实体与其对应
                        对于E2中的一个实体来说,E1中最多存在一个实体与其对应
                    * 一对多的联系: (1:n)  E1中的一个实体可以与E2中的多个实体相对应,E2中的一个
                        实体最多与一个E1中的实体相对应。
                    * 多对多的联系: (m:n)  E1中的一个实体可以与E2中的多个实体相对应,E2中的一个
                        实体与E1中的多个实体相对应。

    2、E-R图的画法:
        * 实体型:用矩形表示,矩形内写明实体名
        * 属性:属性用椭圆表示,并用无向边将其与它对应的实体型连接起来
        * 联系:用菱形表示,菱形内写明联系名,并用无向边分别与相关的实体型连接起来

    3、采用E-R模型进行数据库的概念设计的步骤:

        * 首先设计 局部E-R 模型
            * 步骤:
                – 确定局部结构范围
                    • 范围的划分要自然,易于管理;界面要清晰;大小要适度
                – 确定实体
                    • 采用人们习惯划分;避免冗余;依据用户的需求
                – 确定属性
                    • 属性应该是不可再分解的语义单位
                    • 实体与属性之间的关系只能是1:n
                    • 不同实体类型的属性之间应无直接关联关系
                – 确定实体间联系
                    • 确定联系,联系类型, 防止冗余
            * 两条准则
                • 属性不能具有需要描述的性质
                • 属性不能与其他实体具有联系

        * 然后把各局部E-R 模型综合成一个 全局ER 模型:
            * 步骤
                * 确定公共实体类型
                    • 根据实体类型名和键来认定公共实体类型
                * 合并局部ER模型
                    • 首先进行两两合并,先合并那些现实世界中有联系的局部结构
                    • 合并从公共类型开始,最后再加入独立的 局部结构
                * 消除冲突
                    • 属性冲突:
                        * 属性域冲突: 属性的取值类型、取值范围或取值集合不同。
                            eg. 有的部门把零件号定义为整数类型,有的定义为字符型
                            解决方法:各部门讨论协商
                        * 属性取值单位冲突: 不同的子系统对同一属性的取值 单位选用不同
                            eg. 零件重量有的部门以公斤为单位,有的以斤为单位。
                            解决方法:各部门讨论协商

                    • 命名冲突:
                        * 同名异意: 不同意义的对象在不同的领域具有相同的名字
                            eg. 用 强壮 分别描述男生和女生
                        * 异名同意: 相同意义的对象在不同的领域具有不同的名字。
                            eg. 帅哥 欧巴 .....
                            解决方法:各部门讨论协商

                    • 结构冲突:
                        * 同一对象在不同的应用中具有不同的抽象:
                            eg. 职工在某个局部被当作实体,在另一个局部被当作属性
                            解决方法:按照一定的规则,将属性变为实体 或 将实体变为属性

                        * 同一实体在不同的子系统中包含的属性个数和属性排列次序不完全相等
                            eg. 一个部门只关注员工的姓名和年龄,另一个部门只关注员工的工资
                            解决方法:取各个子系统中 这个实体的属性的并集。

                        * 实体间的联系类型在不同的 子系统中各不相同
                            eg. E1 和 E2 在一个关系中是一对多,在另一个关系中是多对多
                            解决方法:根据应用的语义对实体联系进行综合的分析。

        * 最后对全局E-R 模型进行优化,得到最终的ER 模型,即概念模型
            * 优化原则:
                – 合并实体类型
                – 消除冗余属性
                – 消除冗余联系

    
    3、将E-R图转换成关系模式集

        * 步骤:
            将实体类型转换为一个关系模式,实体的属性就是关系模式的属性,实体标识符即为关系模式的键。

        * 二元联系类型的转换:

            * 若实体间联系是1:1 : 可以在两个实体类型转换成的两个关系模式中任意一个关系模式的属性中加入另
                一个关系模式的键和联系类型的属性。
                (口诀:在一方加入另一方的主键作为外键)
            * 若实体间联系是1:n : 则在n 端实体类型转换成的关系模式中加入1 端实体类型的键和联系类型的属性。
                (口诀:在多方加入一方的主键作为外键,同时把联系的属性也加到多方去)
            * 若实体间联系是m:n : 则将联系类型也转换成关系模式,其属性为两端实体类型的键加上联系类型的属
                性,而键为两端实体键的组合。
                (口诀:将联系本身转换成一个关系模式,联系的名字就是关系模式的名字,它包含的属性由联系双方
                的主键和这个联系本身的属性组成,这个关系模式的主键是两个实体标识符的组合)

        * 三元联系类型的转换:

            * 若实体间联系是1:1:1 ,可以在转换成的三个关系模式中任意一个关系模式的属性中加入另两个关系模
                式的键(作为外键)和联系类型的属性。
            * 若实体间联系是1:1:n ,则在n 端实体类型转换成的关系模式中加入两个1端 端实体类型的键(作为外
                键)和联系类型的属性。
            * 若实体间联系是1:m:n ,则将联系类型也转换成关系模式,其属性为三端实体类型的键加上联系类型的
                属性,而键为m 端和n 端实体键的组合。
            * 若实体间联系是m:n:p ,则将联系类型也转换成关系模式,其属性为三端实体类型的键加上联系类型的
                属性,而键为三端实体键的组合。


    4、采用E-R模型的逻辑设计步骤:
        (1) 导出初始关系模式集
            根据上面E-R图的转化结果可得到初始的关系模式图。

        (2) 规范化处理
        --数据库的逻辑设计 结果不唯一,直接根据E-R图转换而来的关系模式很可能规范性很低(如:只满足1NF)
            这时需要对其进行规范化处理。

            * 逐一考察关系模式判断它们是否满足 规范要求。
            * 通过模式分解关系模式化为满足更高范式的关系模式。

        (3) 模式评价
        (4) 模式修正
        (5) 设计子模式(外模式)
        (6) 设计物理结构



    三、UNML模型(Unified Modeling Language):
        * UML 用于面向对象建模,但是现在也用于数据库建模
        * UML 与 E-R 模型相似,但是不提供多元联系

        * UML 和 ER模型的属于对比

            U M L 模 型 术 语                           E - R 模 型 术 语

            Class(类)                                 Entity set(实体集)
            Association(关联)                         Binary relationship(二元联系)
            Association Class(关联类)                 Attributes on a relationship(联系的属性)
            Subclass(子类)                            Isa hierarchy(Isa层次关系)
            Aggregation(聚集)                         Many-one relationship(多对一联系)
            Composition                                 Many-one relationship with referential integrity
            (组成)                                            (带参照完整性的多对一联系)

        由于板书困难   详情见  https://www.bilibili.com/video/BV1ra4y1t7xY?p=32 




********************************************  数据库恢复技术  **********************************************

一、事务

    1、概念:
        - 事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
        - 事务是数据库的逻辑工作单位。

    2、事务的ACID特性:
        * 原子性:
            事务时数据库的逻辑工作单位,事务中的诸操作要么全做,要么全不做。

        * 一致性:
            事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。

            * 补充:一致性是指数据处于一种语义上的有意义且正确的状态。
            * 举个栗子
                张三给李四转账100元。事务要做的是从张三账户上减掉100元,李四账户上加上100元。一致性
                的含义是其他事务要么看到张三还没有给李四转账的状态,要么张三已经成功转账给李四的状态,
                而对于张三少了100元,李四还没加上100元这个中间状态是不可见的。

        * 隔离性:
            一个事务的执行不能被其他事务干扰。
            即,一个事务的内部操作和使用的数据对其他的并行事务时隔离的,并发执行的各个事务之间不能互相干扰。

        * 持续性:
            也称永久性,指事务一旦提交,他对数据库中的数据的修改就是永久的。接下来的其他操作或故障不会
            对其执行结果有任何影响。

        * 补充:

            * 原子性和一致性的区别:
                原子性和一致性的的侧重点不同:原子性关注状态,要么全部成功,要么全部失败,不存在部分成功的状态。
                一致性关注数据的可见性,中间状态的数据对外部不可见,只有最初状态和最终状态的数据对外可见。

            * 关于一个事务执行过程中,中间产生的数据变化何时写入物理数据库(磁盘)的问题
                - 事务执行的过程中,即使事务还没有执行完毕,它已执行部分对数据库的修改也可能写入磁盘。
                - 事务执行完毕并提交后,修改的数据可能仍在缓冲区中,并未更新到磁盘。

            * 事务四大性质的总结:
                - 在事务处理的ACID属性中,一致性是最基本的属性,其它的三个属性都为了保证一致性而存在的。
                - 事务的原子性由数据库管理系统保证,为了实现原子性,需要通过日志(所有对数据的更新操作都
                    会被写入日志)。如果一个事务的一部分操作已经成功,但以后的操作由于 断电/系统崩溃 等
                    无法正常执行,则通过回溯日志,将已经执行成功的操作撤销,从而达到"全部操作失败"的目的。
                - 在事务处理的ACID属性中,一致性是最基本的属性,其它的三个属性都为了保证一致性而存在的。
                - 但是,原子性并不能完全保证一致性。在多个事务并行进行的情况下,即使保证了每一个事务的原
                    子性,仍然可能导致数据不一致的结果。
                    * 例如,事务1需要将100元转入帐号A:先读取帐号A的值,然后在这个值上加上100。但是,在
                    这两个操作之间,另一个事务2修改了帐号A的值,为它增加了100元。那么最后的结果应该是A增
                    加了200元。但事实上,事务1最终完成后,帐号A只增加了100元,因为事务2的修改结果被事务1
                    覆盖掉了。
                - 为了保证并发情况下的一致性,引入了隔离性,即保证每一个事务能够看到的数据总是一致的,就好
                    象其它并发事务并不存在一样。用术语来说,就是多个事务并发执行后的状态,和它们串行执行后
                    的状态是等价的。(用X锁和S锁实现隔离性) 


二、故障的种类:

    1、事务故障:
        - 事务故障指事务没有达到预期的终点。
        - 发生事务故障时,数据库可能处于不正确状态。

        * 恢复思路:
            - 事务撤销:在不影响其他事务运行的情况下,强行回滚该事务,撤销该事务对数据库进行的所有修改,使
                该事务好像从来没有执行过一样。

    2、系统故障:
        - 指某些事件造成系统停止运转,需要重新启动。如cpu故障,DBMS故障,操作系统故障等。
        - 系统故障影响所有正在运行的事务,但不破坏数据库。

        * 恢复思路:
            - 撤销所有未完成事务,应且重做所有已提交的事务。

    3、介质故障:
        - 指外存故障,如磁盘损坏,磁头碰撞,瞬时强磁场干扰等。
        - 系统故障将破坏数据库,或部分破坏数据库,并影响正在存取这部分数据的所有事务。

        * 恢复思路:
            一般通过数据备份和日志文件配合恢复。

    4、计算机病毒:
        - 略


三、恢复技术的实现:

    1、数据转储:
        - 数据库管理员定期的将整个数据库复制到其他存储介质上的过程。(其他存储介质包括:磁带、磁盘等)
        - 这些备用数据被称为 "后备副本" 或 "后援副本" 。

        * 静态转储:在系统中无运行事务的时候进行转储操作。
        * 动态转储:在转储期间允许对数据库中的数据进行存取和修改。
        * 海量转储:每次转储整个数据库的数据。
        * 增量转储:只转储上一次转储后更新过的数据。

    2、登记日志文件:
        * 日志文件:
        --日志文件是用来记录事务对数据库的更新操作 的文件。

            * 日志文件需要登记的内容有:
                - 各个事务的开始标记    (begin transaction)
                - 各个事务的结束标记    (commit 或 rollback)
                - 各个事务所有的更新操作

            * 每个日志记录的内容包括:
                - 事务的标识    (标明是哪个事务)
                - 操作类型  (事务对数据库的更新类型-删除-插入或修改)
                - 操作的对象    (记录操作的是数据库的哪个对象)
                - 更新前数据的旧值  (对插入操作来说,此项为空)
                - 更新后数据的新值  (对删除操作来说,此项为空)

            * 日志文件的作用
                - 事务故障恢复和系统故障恢复必须用到日志文件
                - 在动态转储方式中,必须建立日志文件,后备副本和日志文件配合起来才能有效的恢复数据库。
                - 静态转储也要建立日志文件,数据库毁坏后,可装入后援副本把数据库恢复到转储结束时刻的
                    正确状态,然后用日志文件把已完成的事务进行重做处理,对故障发生时未完成的事务做撤销处理
                    这样既可将数据库恢复至故障发生时的状态。

            * 登记日志文件的两条原则:
                - 登记的次序严格按照并发事务执行的时间顺序。
                - 必须先写日志文件,后写数据库。

    3、事务故障的恢复

        * 事务故障的修复:(由系统自动完成,不需要用户干预)
            概括:
                由恢复子系统应利用日志文件撤消(UNDO )此事务已对数据库进行的修改

            具体步骤:
                (1) 反向扫描文件日志( 即从最后向前扫描日志文件) ,查找该事务的更新操作
                (2) 对该事务的更新操作执行逆操作。即将日志记录中“更新前的值”写入数据库
                    – 如果记录中是插入操作,则相当于做删除操作( 因为此时“更新前的值”为空 )
                    – 若记录中是删除操作,则相当于做插入操作( 因为此时“更新后的值”为空 )
                    – 若是修改操作,则相当于用修改前值代替修改后值
                (3) 继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理
                (4) 如此处理下去,直至读到此事务的开始标记,事务故障恢复就完成了

        * 系统故障的修复:(由系统自动完成,不需要用户干预)
            概括:
                (1) 撤消故障发生时未完成的事务
                (2) 重做已完成的事务

            具体步骤:
                (1) 正向扫描日志文件(即从头扫描日志文件)
                    – 找出在故障发生前已经提交的事务, 将事务标识记入重做队列
                    – 同时找出故障发生时尚未完成的事务, 将事务标识记入撤消队列
                (2) 对撤消队列中的各个事务进行撤消(UNDO) 处理
                    – 反向扫描日志文件,对每个UNDO 事务的更新操作执行逆操作,即将日志记录中“更新前的值”写入数据库
                (3) 对重做队列中的各个事务进行重做(REDO) 处理
                    – 正向扫描日志文件,对每个REDO 事务重新执行登记的操作。即将日志记录中“更新后的值”写入数据库

        * 介质故障的修复:
            概括:
                (1) 重装数据库,使数据库恢复到一致性状态
                (2) 重做已完成的事务

            具体步骤:
                (1) 装入最新的后备数据库副本,使数据库恢复到最近一次转储时的一致性状态。
                    – 对于静态转储的数据库副本,装入后数据库即处于一致性状态
                    – 对于动态转储的数据库副本,还须同时装入转储时刻的日志文件副本,利用与
                        恢复系统故障相同的方法(即REDO+UNDO ),才能将数据库恢复到一致性状态。
                (2) 装入有关的日志文件副本,重做已完成的事务。
                    – 首先扫描日志文件,找出故障发生时已提交的事务的标识,将其记入重做队列。
                    – 然后正向扫描日志文件,对重做队列中的所有事务进行重做处理。即将日志记录中“更新后的值”写入数据库。

            注意:
                介质故障的修复需要DBA介入,DBA的工作如下:
                    • 重装最近转储的数据库副本和有关的各日志文件副本
                    • 执行系统提供的恢复命令
                (具体的恢复操作仍由DBMS 完成)



********************************************  并发控制  **********************************************

一、并发控制

    1、并发处理事务带来的问题

        * 在并发操作中,DBMS需要对并发操作进行正确的调度,否则将会导致数据不一致。

        * 数据不一致的类型
            - 丢失修改:事务T1和T2读入同一个数据并修改,T2提交的结果破坏了T1提交的结果,使得T1的修改丢失。

            - 不可重复读:事务T1会对某一个数据进行多次的读入,T2则会对这个数据进行修改。如果T1两次读入该
                数据的中间,T2对该数据进行了修改,将导致T1两次读入的数据不一致。

            - 读"脏"数据:事务T1想读入某个数据并对其进行修改,事务T2也会读入该数据使用,若T1读入该数据并
                修改后,T2读入了修改后的数据,此时由于某种原因事务T1被撤销,此时T2读入的数据与数据库中的
                数据不一致。
    2、封锁
        * 锁的类型:
            - 排他锁(写锁-X锁):T对对象A加X锁,则只有T能对A进行读写操作,其他对象只能等待。
                T对A加了X锁后,其他事务不能对A加任何锁,直到T释放X锁。
            - 共享锁(读锁-S锁):T对对象A加S锁,则只有T能读A但不能修改A,此时其他事务也能读A。
                T对A加了S锁后,其他事务只能对A加S锁,不能加X锁,直到T释放S锁。
        
        * 封锁协议:
        --在运用X锁和S锁对数据对象加锁时,需要约定一些规则,叫做封锁协议。
            eg. 何时申请X锁,S锁、持锁时间、何时释放等。

            * 一级封锁协议: 事务T在修改数据R之前,必须先对其加X锁,直到事务结束才释放X锁
                (解决了 丢失修改 的问题)
            * 二级封锁协议: 在一级封锁协议的基础上,T在读数据R前,要先对R加S锁,读完即可释放S锁
                (解决了 读脏数据 的问题)
            * 三级封锁协议:在一级封锁协议的基础上,T在读数据R前,要先对R加S锁,直到事务结束才可释放S锁
                (解决了 不可重复读 的问题)

    3、死锁和活锁

        * 活锁:
        --类似于操作系统的饥饿状态、指许多事务同时申请封锁某数据时,由于系统的调度策略不合理,可能导致
            某个事务一直处于等待状态。

            * 解决方法:采用合适的调度策略,如先来先服务等。

        * 死锁:
        --多个事务各封锁一个数据后,互相请求求封锁对方已经封锁的数据,导致双方的封锁请求都永远得不到满足。
            这种情况称为死锁。

            * 死锁的预防:
                - 一次封锁法:事务T必须一次将其要用到的数据全部封锁,否则就不执行事务T。
                - 顺序封锁法:预先对数据对象规定一个封锁次序,所有事务都要按照这个封锁次序实施封锁。

            * 死锁的诊断与解除:
                * 诊断
                    - 超时法:一旦一个事务的执行时间超过预设的时间,就认为该事务发生了死锁。
                    - 事务等待图法:事务等待图是一个有向图,如果这个有向图出现回路,代表发生死锁。
                * 解除
                    选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有锁,使其他事务
                    能运行下去。

    4、并发调度的可串行化:
        * 正确调度
            一个并发调度,当且仅当它时可串行化的,才称它是正确的调度。
        * 可串行化调度
            说多个并发事务的执行是正确的,当且仅当它的执行结果和按照某一次序串行的执行这些事务所得到
            的结果相同。称这种调度是可串行化的调度。
        * 冲突可串行化调度
            - 冲突操作:
                不同事务对同一数据的读写操作和写写操作
                Ri(x) 和 Wj(x)      即 事务i读数据x、事务j写数据x
                Wi(x) 和 Wj(x)      即 事务i写数据x、事务j写数据x

                - 不可交换的操作
                    不同事务的冲突操作 和 同一事务的两个操作
                    即 Ri(x) 和 Wj(x) 、 Wi(x) 和 Wj(x) 、 Ri(x) 和 Wi(x) 、 Wi(x) 和 Wi(x)

                - 可交换的操作
                    不同事务对同一数据的读读操作 和 不同事务对不同数据的所有操作
                    即 Ri(x) 和 Rj(x)、Ri(x) 和 Rj(x)、Ri(x) 和 Rj(y)、Ri(x) 和 Wj(y)、Wi(x) 和 Wj(y)

            - 冲突可串行化
                如果一个调度序列Sc通过交换 可交换操作 改变调度顺序,得到Sc' 。如果Sc' 是可串行化的调度
                则称Sc是冲突可串行化的调度。

                * 如果一个调度是冲突可串行化的,那么它一定是可串行化的调度。(反之不一定成立)


        * 两段锁协议:
        --为了实现并发调度的可串行化,目前DBMS普遍采用 两段锁协议。

            * 两段锁协议的内容:
            --把事务分为两个阶段,第一个阶段 获得封锁,也称扩展阶段。第二个阶段 释放封锁,也称收缩阶段。

                * 扩展阶段:事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何类型的锁。
                * 收缩阶段:事务可以释放任何任何类型的锁,但是不能申请任何锁。
                
                小提示: 也就是说,每个事务中,申请锁的操作必须全在一个事务的前面,释放锁则在后面。
                    eg. Slock A; Slock B;Xlock C;    Unlock B;Unlock A;Unlock C;  符合
                        |  ----  扩展阶段  ----  |   |  ----   收缩阶段   ----  |

                    eg. Slock A; Unlock A;Xlock C;    Unlock C;Slock B;Unlock B;  不符合

                * 遵循两段锁协议的调度一定是可串行化的调度。反之不一定成立。