zoukankan      html  css  js  c++  java
  • 【数据库范式】第二范式分析

    2、第二范式2NF

    定义:数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖,即符合第二范式。

     简单的说就是不要字段冗余

    《注:什么是函数依赖,详见百度百科(http://baike.baidu.com/view/40008.htm)

    如果一个表中某一个字段A的值是由另外一个字段或一组字段B的值来确定的,就称为A函数依赖于B。》

    2NF可以减少插入异常,删除异常和修改异常。

     

    简单的说,一方面,第二范式肯定要满足第一范式,否则就没有必要谈第二范式。

    另一方面,当某张表中的非主键信息不是由整个主键函数来决定时,即存在依赖于该表中不是主键的部分或者依赖于主键一部分的部分时,通常会违反2NF

     

    我们再来看上面的满足1NF的表1-2

    CardNo

    StudentNo

    StudentName

    Sex

    Academy

    Major

    class

    CardCash

    UserID

    UserLevel

    Date

    Time

    001

    021101

    小明

    教育学院

    心理系

    1

    100

    Operator

    操作员

    2011/10/03

    09:00

     

    我们看到,在这张表中,通过CardNoStudentNo就可以确定StudentNameSexAcademy,MajorclassCardCashUserIDDateTime。所以可以把CardNoStudentNo的组合作为主键。

    但是,我们发现CardCash并不完全依赖于CardNoStudentNo,仅仅通过CardNo就可以确定CardCash,因为一张卡,一定会有卡内金额。这就造成了部分依赖。出现这种情况,就不满足第二范

    修改为:

     

     

    我们再来看另一个例子,学生上下机记录表,会更明显些。表2-1

    CardNo

    StudentNo

    StudentName

    Sex

    Department

    Major

    class

    OnDate

    OnTime

    OffDate

    OffTime

    ConsumeTime

    ConsumeMoney

    001

    0211

    小明

    教育学院

    心理系

    1

    2011/10/14

    09:00

    2011/10/14

    10:00

    1

    2

     

    我们看到,在这张表中,StudentName,Sex,DepartmentMajorclass都是直接依赖于StudentNo,而不依赖与表中的其他字段,这样的设计也不符合2NF非主键信息不是由整个主键函数来决定时。

     

    我们可以把1-22-1优化为:

    3-1

    StudentNo

    CardNo

    UserID

    UserLevel

    Date

    Time

    021101

    001

    Operator

    操作员

    2011/10/03

    09:00

    3-2

    CardNo

    CardCash

    001

    98

    3-3

    CardNo

    OnDate

    OnTime

    OffDate

    OffTime

    ConsumeTime

    ConsumeMoney

    001

    2011/10/14

    09:00

    2011/10/14

    10:00

    1

    2

    3-4

    StudentNo

    StudentName

    Sex

    Academy

    Major

    class

    021101

    小明

    教育学院

    心理系

    1

    ----------------------------------------

    第二范式

     

    每一行的数据只能与其中一列相关,即一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来。

     

     

    一个人同时订几个房间,就会出来一个订单号多条数据,这样子联系人都是重复的,就会造成数据冗余。我们应该把他拆开来。

     

     

     

     

     

    这样便实现啦一条数据做一件事,不掺杂复杂的关系逻辑。同时对表数据的更新维护也更易操作。

     

    ----------------------------------------

    2.第二范式(确保表中的每列都和主键相关)

    第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

    比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示。

     订单信息表

    这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。

    而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示。

    这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可。

     

  • 相关阅读:
    Python_代码练习_写一个判断是否为小数的函数
    Python学习杂记_11_函数(一)
    Ubuntu Server 16.04设置WiFi
    ubuntu 16.04 php 安装curl方法
    Ubuntu上搭建Git服务器
    Ubuntu 16.04 安装 Apache, MySQL, PHP7
    iOS 创建framework & bundle 主要配置
    ios 改变push方向,可以把present改为push方式
    ubuntu环境下使用apt-get配置apache+php+mysql
    [Android Studio] *.jar 与 *.aar 的生成与*.aar导入项目方法
  • 原文地址:https://www.cnblogs.com/viewcozy/p/4652328.html
Copyright © 2011-2022 走看看