• 数据库三范式



    数据库三范式

    设计表的依据。按照这个三范式设计的表不会出现数据冗余和空间浪费。

    数据库三范式:

    1. 第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分。
    2. 第二范式:建立在第一范式的基础之上,所有非主键字段完全依赖主键,不能产生部分依赖。
    3. 第三范式:建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。

    详细解释

    1、第一范式任何一张表都应该有主键,并且每一个字段原子性不可再分

    第一范式:

    ​ 第一范式最核心,最重要的范式,所有表的设计都要满足!

    ​ 必须要有主键,并且每一个字段的原子性不可再分!

    例:``student`表

    学生编号学生姓名联系方式
    1001张三zhangshan.com,10086
    1002李四lisi.com,1008611
    1001王五wangwu.com,1008612

    上表不满足第一范式:

    • 没有主键(学生编号存在重复)
    • 联系方式字段不满足原子性不可再分(可以再分为 邮箱和电话号码)

    修改为满足第一范式的表:

    学生编号(pk)学生姓名邮箱电话
    1001张三zhangsna.com10086
    1002李四lisi.com1008611
    1003王五wangwu.com1008612

    2、第二范式:建立在第一范式的基础之上,所有非主键字段完全依赖主键,不能产生部分依赖

    第二范式:

    • 满足第一范式
    • 非主键字段完全依赖主键,不能产生部份依赖

    例如:

    学生编号学生姓名教师编号教师姓名
    1001张三001王老师
    1002李四002李老师
    1003王五001王老师
    1001张三002李老师

    分析上表是否满足第一范式?

    -------- 不满足,(没有主键)

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

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

    学生编号、教师编号这两个字段做符合主键,经过修改后上表满足了第一范式,但是满足第二范式嘛?

    -------- 不满足:1001--> 张三001--> 王老师(张三依赖于001、王老师依赖于001),显然非主键字段产生了对主键的部份依赖!

    产生部份依赖有什么缺点:数据冗余、空间浪费。(张三重复了,王老师重复了!)


    为了满足第二范式,你必须这样设计:

    学生和教师是多对多的关系!!!!!

    student表:

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

    teacher表:

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

    s_t表(学生教师关系表):

    id(pk)学生编号(fk)教师编号(fk)
    11001001
    21001002
    31002002
    41003001

    口诀:多对多怎么设计?

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

    3、第三范式:建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖

    第三范式:

    • 满足第二范式
    • 所有非主键字段直接依赖主键,不能产生传递依赖。

    例如:学生班级表

    学生编号(pk)学生姓名班级编号班级名称
    1001张三01一班
    1002李四02二班
    1003王五03三班
    1004赵六03三班

    上表是否满足第二范式?

    --------------满足


    是否满足第三范式?

    -------------不满足:1001 ---> 张三1001 ---> 01,那么1001 --- > 01产生了传递依赖,不符合三范式的要求。产生了数据的冗余(三班重复了)

    优化:班级和学生是一对多的关系!

    怎么设计一对多?

    class班级表:

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

    studet表():

    学生编号学生姓名班级编号(fk)
    1001张三01
    1002李四02
    1003王五03
    1004赵六03

    一对多建表口诀:

    一对多,两张表,多的加外键

    数据库表的设计总结

    一对多:一对多,两张表,多的加外键

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

    一对一:一对一,外键唯一

    一对一

    一对一放到一张表不就行了吗?还要拆分?

    在实际开发中,可能一张表的字段太多了,太过于庞大,这个时候需要拆表:

    没有拆表前:一张表

    user表:

    id login_name login_pwd realname gender email phone address …

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

    1 张三 123 …

    2 李四 456 …

    这种庞大的表建议拆分为两张表:

    user_login登录信息表:

    id(pk) login_name login_pwd

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

    1 张三 123

    2 李四 456

    user_detail用户信息表:

    id(pk) realname gender email phone address … login_id(fk + unique)

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

    001 张三 … 1

    002 李四… 2

    问题来了,一张表拆分为两张表,怎么保证为是一对一

    • 一种方案是:共享主键(同主键)—— 用的少
    • 常用方案:设置唯一外键(fk + unique)

    口诀:一对一表拆分

    一对一,外键唯一

    表设计以满足客户需求为准

    注意:数据库三范式是理论上的。实际和理论是有偏差的。

    最终目的是为了满足用户的需求,有的时候会拿冗余来换取速度。

    因为在执行sql语句时,表和表之间的连接次数越多,查询效率越慢(笛卡尔积)

    有的时候会存在冗余,但为了减少连接的次数,这样做也是合理的。(就比如上述一对一的表拆分,其实一张表就可以了,只不过表字段多,但相比于拆分为两张表来说,它的查询效率是更高的!)

  • 相关阅读:
    【java期末复习题】第1章 Java 程序设计语言概述
    【Spring Cloud】网关Gateway的请求过滤工厂RequestRateLimiterGatewayFilterFactory
    Helm Deploy Online Rancher Demo
    力扣 1856. 子数组最小乘积的最大值
    会计学原理知识点总结
    【Linux升级之路】6_进程间通信
    FreeBASIC通过Delphi7 DLL调用MS SOAP使用VB6 Webservice
    Oracle 客户体验 (Oracle CX) 怎么样?
    vue3 自定义loading
    【全栈】vue3.0 + golang 尝试前后端分离【博客系统1.1】有进展了
  • 原文地址:https://blog.csdn.net/qq_54773252/article/details/127585087