数据库学习 - 关系型数据库设计理论

有时候想开始撸代码做系统设计的时候,会有好心的前辈提醒我,“ 小伙子要用数据库吧?记得先设计设计哦,别乱扯张表就用哦!”

一开始我并不明白,数据库应该怎样设计,直到在学习中学到了 关系型数据库设计理论...

  • 说白了,首先你要得知道 什么不好
  • 或者说:不好的关系模式 到底存在着哪些异常
  • 并且要明白 什么是 函数依赖(部分的、完全的、传递的 几种都要了解。)
  • 然后就是最重要的了!要学会从 1NF 也就是 第一范式 到 BCNF 的辨认与化解(这个最难啦!要啃透呀~)

数据库逻辑设计主要解决的问题:

  • 关系数据库应该组织成几个关系模式
  • 关系模式中包括哪些属性

并在关系数据库设计理论的指导下,选择比较好的关系模式集合。

举个栗子是最好的学习方法:

  • 我们要为教务处设计一个关系数据库:

    关系模式是:UN( Sno, Cno, G, Sdept, MN)

    其中:

    • Sno:描述学生
    • Sdept:描述系名
    • MN:描述系主任
    • Cno:描述课程
    • G:描述学习成绩

通过对实际情况的分析:可知 ( Sno, Cno )是码。

那么装入一些数据后,问题就暴露出来了:

5.1.1

对数据操作时,会出现以下问题:

  1. 数据冗余( 你看看 系主任名 存了多少次?)

    数据重复存储:浪费了存储空间,数据库维护起来会很困难;(更新异常)

  2. 插入异常( 一个系刚刚成立时... )

    主码为空的记录不能存在于数据库,所以本来其实是有这个系的,但是这个系没学生,所以在这张表上就列不出来!

  3. 删除异常 ( 想想一个系的学生如果全部毕业后... )

    删除操作后,有些相关的信息在该数据库中就消失了,无法保存下来。

要消除上面提到的这些弊端,我们可以把关系数据库模式分解为三个关系模式:

  • S( Sno, Sdept ) 即 学生表
  • SG( Sno, Cno, G ) 即 学生课程的成绩表
  • Dept( Sdept, MN ) 即 系的信息表

函数依赖是什么

  • 定义

    类似于变量之间的单值函数关系 y = f(x) ,其中自变量 x 的值,决定一个唯一的函数值 y

  • 在一个关系模式里的属性,由于它在不同元组里的属性值 可能不同,由此可以吧关系中的属性看作是 变量。

  • 函数依赖就是属性间的逻辑依赖关系。一个属性与另一个属性再取值上可能存在制约关系。

  • x 通常称为 “ 决定因素

  • 说明

    1. 函数依赖是语义范畴的概念,它反应的是语义完整性约束。你只能通过一句话中所表达、描述的语义来确定一个函数依赖。

    2. 函数依赖是指 某关系模式中 所有关系元组都要满足的条件,不是某个或某些元组满足一下就可以了!

    3. 函数依赖与属性间的联系类型有关

      建议参见 上一节 E-R 图的对应部分一起理解...

      (1) 若属性 x 与属性 y 之间有 “一对一” 的联系,则 x, y 之间互为函数依赖。

      (2) 若属性 x 与属性 y 之间有 “多对一”的联系,则 y 函数依赖 x,但 反之 y 则不。

      (3) 若属性 x 与属性 y 之间有 “多对多”的联系,则 x, y 之间不存在任何函数依赖。

    4. 若 x 函数依赖 y 并且 y 不是 x 的子集,则称 y 函数依赖 x 是 非平凡的函数依赖。 (所以如果 y 是 x 的子集则是平凡的)

      我们一般讨论的都是 非平凡的函数依赖

部分、完全、传递 函数依赖

部分函数依赖:设 X, Y 是关系 R 的两个属性集合,存在 X→Y ,若 X’ 是 X 的真子集,存在 X’→Y,则称 Y 部分函数依赖于 X 。

  • 举个例子:学生基本信息表 R 中(学号,身份证号,姓名),当然学号、身份证属性的取值是唯一的,所以在R关系中,

    • (学号,身份证号)x ->(姓名)y
    • (学号)x'1 ->(姓名)y
    • (身份证号)x'2 ->(姓名)y ;
  • 所以姓名 部分函数依赖于(学号,身份证号);

完全函数依赖:设 X, Y 是关系 R 的两个属性集合,X’ 是 X 的真子集,存在 X→Y ,但对每一个 X’ 都有 X’ !→Y ,则称 Y 完全函数依赖于 X 。

  • 再举个例子:学生基本信息表 R(学号,班级,姓名)

  • **假设不同的班级学号有相同的,班级内学号不能相同。 ** 则在R关系中:

    • (学号,班级)x ->(姓名)y

      但是

    • (学号)x'1 -> (姓名) y 不成立

    • (班级)x'2 -> (姓名) y 不成立

  • 所以姓名 完全函数依赖于(学号,班级);

传递函数依赖:设 X, Y, Z 是关系 R 中互不相同的属性集合,存在X→Y( 而 Y !→X ),Y→Z,则称Z传递函数依赖于X。

  • 再举个例子:在关系 R (学号 ,宿舍, 费用) 中:
  • (学号)x ->(宿舍)y
  • (宿舍)y !-> (学号)x
  • (宿舍)y ->(费用)z
  • 所以 符合传递函数依赖 的要求,故:知道了学号,就知道他要交多少宿舍费用了;

第一范式(1NF)

在任何一个关系型数据库中,第一范式(1NF)是对关系模式最基本的要求,不满足你就不是关系数据库。

所谓第一范式(1NF)是指数据库表中的每一列(即每个属性)都是不可分割的基本数据项,同一列中不能拆成多个列再放值。

简言之,第一范式 就是不能有重复的列。

第二范式 (2NF)

自此向下的范式都必须先满足之前的所有范式规范,这就好比一个俄罗斯套娃,哈哈这样好理解吧?

第二范式就是在第一范式的基础上建立起来的。第二范式要求:

  • 数据库表中的每个实例或行必须可以被唯一地区分。为了实现这一点通常需要为表加上一个列,用以存储各个实例的唯一标识,比如 员工信息表加上了员工编号 emp_id 。
  • 这个唯一属性列被称为主关键字或主键、主码

第二范式要求实体的属性 完全依赖于 主关键字。所以化简过程中我们着重解决的问题是:消除非主属性对 的部分函数依赖,采用 投影分解运算 来提高关系模式的范式等级。

简言之,第二范式 就是非主属性依赖于主关键字

第三范式(3NF)

在满足第二范式的基础上,不存在任何传递函数依赖,那么就是第三范式。

简而言之,第三范式 就是属性不依赖于其他非主属性

你可能感兴趣的:(数据库学习 - 关系型数据库设计理论)