热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

关系型数据库范式

设计关系数据库时,为了设计出合理的数据库表结构,需要遵从不同的规范要求,这些规范性要求被称为范式。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范

     设计关系数据库时,为了设计出合理的数据库表结构,需要遵从不同的规范要求,这些规范性要求被称为范式

     目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)

     各种范式呈递次规范,越高的范式数据库冗余越小。满足高层次范式的必定满足低层次范式,如一个数据库设计如果符合第二范式,一定也符合第一范式。

一、基本概念

     1、实体:现实世界中客观存在的并可以相互区分的对象或事物。如"公司"、"项目"、"员工"等。

     2、属性:实体所具有的某一特性。比如"公司名称"、"公司地址"都是实体"公司"的属性。

     3、:表中可以唯一确定一行数据的某个属性[或者属性组]。如[员工号]、[员工号绩效评定月份]。不同的表结构,对应的码不同。下文表(二)中,[员工号绩效评定月份]属性组就是码。

     4、主属性:包含在任何一个码中的属性称为主属性。下文表(二)中,员工号绩效评定月份就是主属性。

     5、非主属性:与主属性相反,没有在任何候选码中出现过,这个属性就是非主属性。下文表二中,员工姓名、部门、部门人数、绩效就是非主属性。

二、第一范式

     1、概述

     第一范式指的是符合第一范式的关系中的每个属性都不可再分

     2、实例分析

     下表(一)中,由于部门信息这个属性可以再分为部门和部门人数这两个属性,所以不符合第一范式。

员工号 员工姓名 部门   绩效评定月份  绩效 
部门 部门人数
10001 张三 开发部 30 201801 90
10001 张三 开发部 30 201802 85
10002 李四 集成部 30 201801 88
10002 李四 集成部 30 201802 87
10003 王五 综合部 5 201802 89
10004 马六 综合部 5 201802 85

表(一)

     将上表修改成如下表,就满足第一范式。

员工号 员工姓名 部门 部门人数 绩效评定月份 绩效
10001 张三 开发部 30 201801 90
10001 张三 开发部 30 201802 85
10002 李四 集成部 30 201801 88
10002 李四 集成部 30 201802 87
10003 王五 综合部 5 201802 89
10004 马六 综合部 5 201802 85

     表(二)

     第一范式是所有关系型数据库的最基本要求,只要在关系型数据库管理系统(RDBMS)中已经存在的数据表,一定是符合第一范式。

     3、不足

       A、数据冗余:如上表中,员工号、员工姓名、部门、部门人数数据重复出现多次。

       B、插入异常:根据三种关系完整性约束中实体完整性的要求,关系中的码所包含的任意一个属性都不能为空,所有属性的组合也不能重复(可以简单的理解为表的主键)。上表中,为了唯一区分每一条记录,需要将(员工号绩效评定月份)作为码。如果一个新建的部门还没有员工的话,那么就无法将部门和部门人数的信息插入到表中,导致插入异常,无法有效记录部门的信息。

       C、删除异常:如果将员工相关的记录都删除,那么部门相关的信息也会删除,导致了删除异常。

       D、修改异常:假如张三转到集成部,为了保证数据库中数据的一致性,需要修改两条条记录中部门与部门人数的数据,导致修改异常。

三、第二范式

     1、概述

     第二范式是为了解决第一范式所带来的问题而设定的规则,它是在第一范式的基础之上,消除了非主属性对于码的部分函数依赖。简单地说,第二范式要求每个非主属性完全依赖于主键,而不是仅依赖于主键其中的一部分属性。

     2、相关概念

     A、函数依赖

     在一张表中,如果在属性(或属性组)X的值确定的情况下,必定能确定属性Y的值,那么就可以说Y函数依赖于X,写作 X → Y。也就是说,在数据表中,不存在任意两条记录,它们在X属性(或属性组)上的值相同,而在Y属性上的值不同。

     在上表(二)中,存在着以下的函数依赖:

      ★ 员工号 → 员工姓名

    ★ 部门 → 部门人数

    ★ (员工号,绩效评定月份) → 绩效

    以下的函数依赖则不成立:

    ★ 员工号 → 绩效评定月份

    ★ 员工号 → 绩效

     B、完全函数依赖

     如果X → Y是一个函数依赖,且对X的任何一个真子集X',都不存在X' → Y,则称X → Y是一个完全函数依赖。为了方便表述,写作X>>Y(非正式方式)。

     在上表中,存在着以下的完全函数依赖:

    ★ 员工号>>员工姓名

    ★ (员工号,绩效评定月份)>>绩效(员工号对应的绩效不确定,绩效评定月份对应的绩效也不确定)

     C、部分函数依赖

     如果X → Y是一个函数依赖,并且存在X的一个真子集X',使得X' → Y,则称X → Y是一个部分函数依赖。为了方便表述,写作X>Y(非正式方式)。

     在上表中,存在着以下的部分函数依赖:

    ★ (员工号,绩效评定月份)>员工姓名

     D、传递函数依赖

     如果X→Y,Y→Z,且Y不属于X,Y → X不成立,则称Z传递函数依赖于X。为了方便表述,写作X>>>Z(非正式方式)。(限定Y不属于X,Y→X不成立,是因为如果Y属于X,那么Z部分函数依赖于X,此时X中存在多余属性;若Y → X成立,则有X和Y等价,则关系中没有必要同时存在X和Y)

     在上表中,存在着以下的传递函数依赖:

    ★ 员工号>>>部门人数(员工号 → 部门,部门 → 部门人数)

     3、实例分析

     根据定义,我们可以知道:第二范式就是判断是否存在非主属性对于码的部分函数依赖,如果存在,则不满足第二范式。

     判断一个表是否符合第二范式,可以通过以下步骤进行判断:

    ★ 找出表中所有的码;

    ★ 根据第一步找出的码,找出所有的主属性;

    ★ 根据主属性,找出所有的非主属性;

    ★ 判断是否存在非主属性对于码的部分函数依赖,由此判定是否符合第二范式;

     我们根据以上步骤来分析一下上表(二):

    ★ 该表的码为:(员工号,绩效评定月份)

    ★ 该表的主属性为:员工号、绩效评定月份

    ★ 该表的非主属性为:员工姓名、部门、部门人数、绩效

    ★ 该表的非主属性对于码的函数依赖关系如下:

      [员工号,绩效评定月份] → 绩效,完全函数依赖;

        [员工号,绩效评定月份]→ 员工姓名,部分函数依赖;因为存在:员工号 → 员工姓名

        [员工号,绩效评定月份]→ 部门,部分函数依赖;因为存在:员工号 → 部门

        [员工号,绩效评定月份]→ 部门人数,传递函数依赖;因为存在:员工号 → 部门,部门 → 部门人数

     由于存在非主属性对于码的部分函数依赖,所以上表不符合第二范式。

     为了符合第二范式的要求,我们必须消除这些部分函数依赖,将大表拆分成更多个更小的表。

     我们将上表拆分成如下的两个表:

员工号 绩效评定月份 绩效
10001 201801 90
10001 201802  85
10002  201801  88
10002  201802  87
10003  201802  89
10004  201802  85

表(三)

员工号 员工姓名 部门 部门人数
10001 张三 开发部 30
10002 李四 集成部 30
10003 王五 综合部 5
10004 马六 综合部 5

表(四)

     两个表的非主属性对于码的函数依赖关系如下:

    ★ [员工号,绩效评定月份]→ 绩效,完全函数依赖;

      ★ 员工号 → 员工姓名,完全函数依赖;

      ★ 员工号 → 部门,完全函数依赖;

      ★ 员工号 → 部门人数,完全函数依赖和传递函数依赖;因为存在:员工号 → 部门,部门 → 部门人数

      由于两个表都符合完全函数依赖,所以两个表都符合第二范式。

     那么第二范式是否解决了第一范式的不足呢?

        A、数据冗余:除部门人数数据重复外,其余无冗余。有改进。

        B、插入异常:根据三种关系完整性约束中实体完整性的要求,关系中的码所包含的任意一个属性都不能为空,所有属性的组合也不能重复(可以简单的理解为表的主键)。员工-部门表中,为了唯一区分每一条记录,需要将员工号作为码。如果一个新建的部门还没有员工的话,那么就无法将部门和部门人数的信息插入到表中,导致插入异常,无法记录部门的信息。无改进

        C、删除异常:表(四)中,如果将员工相关的记录都删除,那么部门相关的信息也会删除,导致了删除异常。无改进

        D、修改异常:假如张三转到集成部,只需要改动对应的部门即可。有改进。

     所以,仅仅符合第二范式的要求,很多情况下还是不够的,为了能进一步解决这些问题,我们还需要将符合第二范式要求的表改进为符合第三范式的要求。而导致这些的原因是传递函数依赖。

三、第三范式

     1、概述

     第三范式是在第二范式的基础之上,消除非主属性对于码的传递函数依赖。

     2、实例分析

     在上述例子中,由于存在员工号与部门人数的传递函数依赖,所以需要将表(四)进行再次拆分,拆分后所有表如下:

员工号 绩效评定月份 绩效
10001 201801 90
10001 201802 85
10002 201801 88
10002 201802 87
10003 201802 89
10004 201802 85

表(五)

员工号 员工姓名 部门
10001 张三 开发部
10002 李四 集成部
10003 王五 综合部
10004 马六 综合部

表(六)

部门 部门人数
开发部 30
集成部 30
综合部 5

表(七)

     以上三个表均满足第三范式,那么第三范式是否解决了第二范式的不足呢?

        A、数据冗余:无冗余。有改进。

        B、插入异常:可以插入部门信息。有改进。

        C、删除异常:删除员工信息,部门信息不会删除。有改进

        D、修改异常:假如张三转到集成部,只需要改动对应的部门即可。有改进。

     所以第三范式基本解决了数据冗余、插入异常、删除异常、修改异常等问题。

四、其它范式(待补充细化)

     A、BCNF范式

   1、所有非主属性都完全函数依赖于每个候选键

   2、所有主属性都完全函数依赖于每个不包含它的候选键

   3、没有任何属性完全函数依赖于非候选键的任何一组属性

     B、第四范式

     解决多值依赖问题,要求把同一表内的多对多关系删除。表示在多对多关系中,实体本身并不存储关系,而关系都记录在另一个中间关系表中,要选择俩个多对多实体间的数据,必须通过中间关系表来得到,实体本身没有存储任何与另外一个实体的关系的记录。

     C、第五范式

     也称投影-连接范式,是数据库规范化的一个级别,以去除多个关系之间的语义相关。一张表满足第五范式当且仅当它的每个连接依赖可由候选键推出。

五、总结

     范式就是在数据库表设计时移除数据冗余的过程。随着范式级别的提升,数据冗余越来越少,但数据库的效率也越来越低。

     一般情况下,数据库设计满足第三范式即可。


推荐阅读
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 2023 ARM嵌入式系统全国技术巡讲旨在分享ARM公司在半导体知识产权(IP)领域的最新进展。作为全球领先的IP提供商,ARM在嵌入式处理器市场占据主导地位,其产品广泛应用于90%以上的嵌入式设备中。此次巡讲将邀请来自ARM、飞思卡尔以及华清远见教育集团的行业专家,共同探讨当前嵌入式系统的前沿技术和应用。 ... [详细]
  • Navicat Premium 15 安装指南及数据库连接配置
    本文详细介绍 Navicat Premium 15 的安装步骤及其对多种数据库(如 MySQL 和 Oracle)的支持,帮助用户顺利完成软件的安装与激活。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • IT项目管理过程中的方法、工具、技术
    工欲善其事,必先利其器。而对于一个软件开发项目,最重要的器就是方法,工具和技术。而这三要素中重要的又是方法论,方法是基础&# ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
author-avatar
我就唔分_753
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有