数据库设计三范式

什么是数据库设计范式?

  • 数据库表的设计依据。教你怎么进行数据库表的设计。

第一范式:

  • 要求任何一张表必须有主键,每一个字段原子性不可再分。

第二范式:

  • 建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖。

第三范式:

  • 建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。

注意:设计数据库表的时候,按照以上的范式进行,可以避免表中数据的冗余,空间的浪费。

1、第一范式: 最核心,最重要的范式,所有表的设计都需要满足。 必须有主键,并且每一个字段都是原子性不可再分。
学生编号      学生姓名         联系方式
------------------------------------------------------
1001          张三            [email protected],1359999999
1002          李四            [email protected],13699999999
1001          王五            [email protected],13488888888

以上是学生表,满足第一范式吗?
不满足,第一:没有主键。第二:联系方式可以分为邮箱地址和电话

学生编号(pk)   学生姓名     邮箱地址        联系电话
----------------------------------------------------
1001            张三       [email protected]   1359999999
1002            李四       [email protected]   13699999999
1003            王五       [email protected]     13488888888
2、第二范式: 建立在第一范式的基础之上, 要求所有非主键字段必须完全依赖主键,不要产生部分依赖。
学生编号    学生姓名   教师编号   教师姓名
----------------------------------------
1001        张三      001       王老师
1002        李四      002       赵老师
1003        王五      001       王老师
1001        张三      002       赵老师

这张表描述了学生和老师的关系:(1个学生可能有多个老师,1个老师有多个学生)
这是非常典型的:多对多关系!

分析以上的表是否满足第一范式?
不满足第一范式。

怎么满足第一范式呢?修改

学生编号+教师编号(pk)            学生姓名      教师姓名
----------------------------------------------------
1001            001             张三          王老师
1002            002             李四          赵老师
1003            001             王五          王老师
1001            002             张三          赵老师

学生编号 教师编号,两个字段联合做主键,复合主键(PK: 学生编号+教师编号)
经过修改之后,以上的表满足了第一范式。但是满足第二范式吗?
不满足,“张三”依赖1001,“王老师”依赖001,显然产生了部分依赖。
产生部分依赖有什么缺点?
数据冗余了。空间浪费了。“张三”重复了,“王老师”重复了。

为了让以上的表满足第二范式,你需要这样设计:
使用三张表来表示多对多的关系!!!!

学生表:

学生编号(pk)        学生名字
---------------------------
1001                张三
1002                李四
1003                王五


教师表:

教师编号(pk)        教师姓名
---------------------------
001                 王老师
002                 赵老师


学生教师关系表:

id(pk)          学生编号(fk)            教师编号(fk)
----------------------------------------------------
1               1001                    001
2               1002                    002
3               1003                    001
4               1001                    002
  • 多对多怎么设计?
    多对多,三张表,关系表两个外键!!!!!!!!!!!!!!!
3、第三范式 第三范式建立在第二范式的基础之上 要求所有非主键字典必须直接依赖主键,不要产生传递依赖。
学生编号(PK)   学生姓名   班级编号        班级名称
---------------------------------------------------------
1001            张三        01            一年一班
1002            李四        02            一年二班
1003            王五        03            一年三班
1004            赵六        03            一年三班

以上表的设计是描述:班级和学生的关系。很显然是1对多关系!
一个教室中有多个学生。

分析以上表是否满足第一范式?
满足第一范式,有主键。

分析以上表是否满足第二范式?
满足第二范式,因为主键不是复合主键,没有产生部分依赖。主键是单一主键。

分析以上表是否满足第三范式?
第三范式要求:不要产生传递依赖!
一年一班依赖01,01依赖1001,产生了传递依赖。
不符合第三范式的要求。产生了数据的冗余。

  • 那么应该怎么设计一对多呢?
    一对多,两张表,多的表加外键!!!!!!!!!!!!
班级表:一

    班级编号(pk)                班级名称
    ----------------------------------------
    01                              一年一班
    02                              一年二班
    03                              一年三班

学生表:多

    学生编号(PK) 学生姓名 班级编号(fk)
    -------------------------------------------
    1001                张三          01          
    1002                李四          02          
    1003                王五          03          
    1004                赵六          03  
4、总结表的设计?
  • 一对多:
    一对多,两张表,多的表加外键!!!!!!!!!!!!

  • 多对多:
    多对多,三张表,关系表两个外键!!!!!!!!!!!

  • 一对一:
    一对一放到一张表中不就行了吗?为啥还要拆分表?
    在实际的开发中,可能存在一张表字段太多,太庞大。这个时候要拆分表。
    一对一怎么设计?
    一对一,外键唯一!!!!!!!!!!

没有拆分表之前:一张表
            t_user
            id      login_name      login_pwd       real_name     email             address........
            ---------------------------------------------------------------------------------------
            1       zhangsan        123             张三          zhangsan@xxx        ...
            2       lisi            123             李四          lisi@xxx            ...
            ...
        
        这种庞大的表建议拆分为两张:
            t_login 登录信息表
            id(pk)      login_name      login_pwd   
            ---------------------------------
            1           zhangsan        123         
            2           lisi            123         

            t_user 用户详细信息表
            id(pk)      real_name       email               address........ login_id(fk+unique)
            -----------------------------------------------------------------------------------------
            100         张三              zhangsan@xxx                                1
            200         李四              lisi@xxx                                    2
备注:

数据库设计三范式是理论上的。

实践和理论有的时候有偏差。

最终的目的都是为了满足客户的需求,有的时候会拿冗余换执行速度。

因为在sql当中,表和表之间连接次数越多,效率越低。(笛卡尔积)

有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的,并且对于开发人员来说,sql语句的编写难度也会降低。

你可能感兴趣的:(数据库设计三范式)