数据库范式解析

一、概述

前段时间自己写项目,在设计数据库的过程中,重新审视了关系型数据库,在此记录整理如下。

  1. 什么是关系型数据库的范式?

    数据库规范化 - Normal Form,又称正规化、标准化,是数据库设计中的一系列原理和技术,以减少数据库中数据冗余,增进数据的一致性。关系模型的发明者埃德加·科德最早提出这一概念,并于1970年代初定义了第一范式、第二范式和第三范式的概念,还与Raymond F. Boyce于1974年共同定义了第三范式的改进范式——BC范式。

  2. 数据库规范化有什么用?

    增进数据一致性,减少数据冗余。


二、范式定义

范式现在发展出了很多种。一般来说,现在数据库设计最多满足1NF - 3NF,范式过高虽然对数据关系有更好的约束性,但也导致数据关系表增加而令数据库IO更易繁忙。

1NF-3NF,每一级NF都必须满足上一级NF:

  1. 1NF:列必须是原子的(列的原子性),不可再分;

  2. 2NF:非主键列必须完全依赖于主键,而不是只依赖某些主键列;

  3. 3NF:非主键列必须直接依赖于主键列,不能存在传递依赖(传递依赖:非主属性A依赖非主属性B,B再依赖主属性C);


三、范式详解

1. 1NF

1.1 解决的问题

排除重复组

1.2 例子

Table_交易↓ 如下

顾客日期数量
PeteMonday19.00 -28.20
PeteMonday-84.00
SarahFriday100.00 -48.20

数量就是“重复组”了。

1.3 解析

  1. 理论上不可能有RDBMS能让你设计出违反1NF的数据表,也就是说RDBMS已经保证其列的原子性了。例如,你定义了一个整数字段来存放数量,你肯定写不出”25,30”这样的值,它是违法的(如果你硬把2530连着写,那表示这是一个原子值)。

  2. 不过就算这样,你还是可以设计出骨子里违反1NF的表,例如

    1. 单一字段中有多个有意义的值

      Table_不喜欢的食物↓

      不喜欢的食物(varchar类型)
      Pete白菜,面包
      Pete泡菜,白菜,西兰花

      a) 显然“不喜欢的食物”是一个RDBMS保证的原子列,但是你利用他是varchar这一点,来自己意淫设计存储了多个逻辑值,然后用逗号分隔他们…… 相信很多人这样干过

      b) 以这样的设计,如果要查询不喜欢白菜的人就很不清晰该怎么做了(还能叫关系型数据库表吗)可能必须使用like%%了。

    2. 用很多字段来表达一个事实

      Table_不喜欢的食物↓

      不喜欢的食物1不喜欢的食物2不喜欢的食物3
      Pete白菜小龙虾芹菜
      Alan泡菜龙虾大闸蟹

      a) 就算我们能确定每个人不喜欢吃的食物最多不会超过三样,这还是一个很糟的设计。举例来说,我们想要知道所有不喜欢同一种食物的人的组合的话,这就不是件容易的事,因为食物有可能出现在任何一个字段,也就是说每一次的查询都要去检查 9 (3 x 3) 组不同的字段组合。


2. 2NF

1.1 解决的问题

1 如果一个数据表只有单一一个主键字段的话,它就一定符合第二范式。
2 错误一般只会发生在想设计有一对多/多对一中多的一方或者是多对多关联表中的联合主键时发生。

1.2 例子

Table_组件来源↓

组件ID(主键)价格供应商ID(主键)供应商名称供应商住址
6559.991Stylized PartsVA
7420.001Stylized PartsVA
6569.992ACME IndustriesCA

1.3 解析

  1. 首先,上表是按多对一设计的(设计错误问题正是我们要说的),1个组件来自于1个供应商,1个供应商可能供应多个组件。

  2. 其次,上表满足了列的原子性,所以符合第一范式。组件ID和供应商ID是联合主键。

  3. 价格根据不同组件和不同供应商才能确定,没问题。

  4. 但供应商名称和供应商地址只是依赖于供应商ID的,跟组件没有关系,这就叫非完全依赖

    1. 正确设计

      Table_供应商↓

      供应商ID(主键)名称价格
      1Stylized PartsVA
      2ACME IndustriesCA

      Table_组件来源↓

      组件ID(主键)价格供应商ID(主键)
      6559.991
      7420.001
      6569.992

3. 3NF

1.1 解决的问题

在2NF基础上,非主键列必须直接依赖于主键。(非主键列之间是独立的没有关系)

1.2 解析

  1. 例子其实可以是上边2NF的列子,它也是不符合3NF的。

  2. 在做数据库表设计时,仔细考虑你写下的非关键字段到底是否直接依赖于主键,这样就能遵守第三范式了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值