MySQL之范式的使用详解

一、范式

范式的英文名称是Normal Form,它是英国人E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出来的。范式是关系数据库理论的基础,也是我们在设计数据库结构过程中所要遵循的规则和指导方法。目前有迹可寻的共有8种范式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF。通常所用到的只是前三个范式,即:第一范式(1NF),第二范式(2NF),第三范式(3NF)。

第一范式(1NF)

第一范式其实是关系型数据库的基础,即任何关系型数据库都是符合第一范式的。简单的将第一范式就是每一行的各个数据都是不可分割的,同一列中不能有多个值,如果出现重复的属性就需要定义一个新的尸实体。
下面数据库便不符合第一范式:

+------------+-------------------+
| workername | company      |
+------------+-------------------+
| John    | ByteDance,Tencent |
| Mike    | Tencent      |
+------------+-------------------+

上面描述的数据所表达的意思是,Mike在Tencent工作,而John同时在ByteDance和Tencent工作(假设这是可能的)。但是这种表达方式并不符合第一范式,即列的数据必须是不可分的,要满足第一范式,必须是下面的这种形式:

+------------+-----------+
| workername | company  |
+------------+-----------+
| Mike    | Tencent  |
| John    | ByteDance |
| John    | Tencent  |
+------------+-----------+

第二范式(2NF)

首先,一个数据库要满足第二范式必须要先满足第一范式。
我们先看一个表格:

+----------+-------------+-------+
| employee | department | head |
+----------+-------------+-------+
| Jones  | Accountint | Jones |
| Smith  | Engineering | Smith |
| Brown  | Accounting | Jones |
| Green  | Engineering | Smith |
+----------+-------------+-------+

这个表描述了被雇佣者,工作部门和领导的关系。这个表所表示的关系在现实生活中是完全可能存在的,现在让我们考虑一个问题,如果Brown接任Accounting部门的领导,我们需要怎样对表进行修改?这个问题将会变得非常麻烦,因为我们会发现数据都耦合在一起了,你很难找到一个很好的能唯一确定每一行的判断条件来执行你的UPDATE语句。而我们把能够唯一表示数据库中表的一行的数据成为这个表的主键。 因此,没有主键的表是不符合第二范式的,也就是说符合第二范式的表需要规定主键。

因此我们为了使上面的表符合第二范式,需要将它拆分为两个表:

+----------+-------------+
| employee | department |
+----------+-------------+
| Brown  | Accounting |
| Green  | Engineering |
| Jones  | Accounting |
| Smith  | Engineering |
+----------+-------------+

+-------------+-------+
| department | head |
+-------------+-------+
| Accounting | Jones |
| Engineering | Smith |
+-------------+-------+

在这两个表中,第一个表的主键为employee,第二个表的主键为department。在这种情况下,完成上面的问题就显得非常简单了。

第三范式(3NF)

一个关系型数据库要满足第三范式必须要先满足第二范式。
将第三范式前,我们同样先看两个表:

+-----------+-------------+---------+-------+
| studentid | studentname | subject | score |
+-----------+-------------+---------+-------+
| 1     | Mike    | Math  | 96  |
| 2     | John    | Chinese | 85  |
| 3     | Kate    | History | 100  |
+-----------+-------------+---------+-------+

+-----------+-----------+-------+
| subjectid | studentid | score |
+-----------+-----------+-------+
| 101    | 1     | 96  |
| 111    | 3     | 100  |
| 201    | 2     | 85  |
+-----------+-----------+-------+

上面的两个表格的主键分别为studentid和subjectid,很显然两个表都符合第二范式。

但是我们会发现这两个表有重复冗余的数据score。因此第三范式就是要消除冗余的数据,具体到上面的情况,就是两个表只有一个能够存在score这一列数据。那么怎么将这两个表联系起来呢,这里就出现了外键。如果两个表中有冗余重复的列,而且这个表中的一个非主键列在另一个表中是主键,那么我们为了消除冗余列可以把这个非主键列作为联系两个表的桥梁,也就是外键。 通过观察可以发现,studentid在第一个表中是主键,在第二个表中是非主键,所以他就是第二个表的外键。因此上述情况我们有了以下符合第三范式的写法:

+-----------+-------------+---------+
| studentid | studentname | subject |
+-----------+-------------+---------+
| 1     | Mike    | Math  |
| 2     | John    | Chinese |
| 3     | Kate    | History |
+-----------+-------------+---------+

+-----------+-----------+-------+
| subjectid | studentid | score |
+-----------+-----------+-------+
| 101    | 1     | 96  |
| 111    | 3     | 100  |
| 201    | 2     | 85  |
+-----------+-----------+-------+

可以发现在设定了外键之后,第一个表即使删除了score列,也可以通过studentid在第二个表中查找到相应的score的值,这样即消除了数据的冗余,又不会影响查找,满足第三范式。

二、范式的优点和缺点

范式的优点

  • 范式化的更新操作通常要比反范式化要快。
  • 当数据较好地范式化时,就只有很少或者没有重复的数据,所以只需要修改更少的数据。
  • 范式化的表通常都比较小,可以更好的放在内存中,所以执行操作会更快。
  • 很少有多余的数据意味着检索列表数据时更少需要DISTINCT或者GROUP BY语句。

范式的缺点

  • 范式化的缺点就是通常需要关联。稍微复杂一些的查询语句在符合范式的数据库上都可能需要至少一次关联,也许更多,这不但代价昂贵,也可能使一些索引策略无效。

到此这篇关于MySQL之范式的使用详解的文章就介绍到这了,更多相关MySQL 范式 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Mysql数据库中数据表的优化、外键与三范式用法实例分析

    本文实例讲述了Mysql数据库中数据表的优化.外键与三范式用法.分享给大家供大家参考,具体如下: 数据表优化 将商品信息表进行优化 1.创建商品种类表: create table if not exists goods_cates( id int unsigned primary key auto_increment, name varchar(40) not null ); 2.将商品种类写入商品种类表中: 注意:插入另一个表的查询结果不需要加values insert into goods_

  • Mysql数据库设计三范式实例解析

    三范式 1NF:字段不可分; 2NF:有主键,非主键字段依赖主键; 3NF:非主键字段不能相互依赖; 解释: 1NF:原子性 字段不可再分,否则就不是关系数据库; 2NF:唯一性 一个表只说明一个事物; 3NF:每列都与主键有直接关系,不存在传递依赖; 第一范式(1NF) 即表的列的具有原子性,不可再分解,即列的信息,不能分解, 只要数据库是关系型数据库(mysql/oracle/db2/informix/sysbase/sql server),就自动的满足1NF.数据库表的每一列都是不可分割的

  • MySQL之范式的使用详解

    一.范式 范式的英文名称是Normal Form,它是英国人E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出来的.范式是关系数据库理论的基础,也是我们在设计数据库结构过程中所要遵循的规则和指导方法.目前有迹可寻的共有8种范式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF.通常所用到的只是前三个范式,即:第一范式(1NF),第二范式(2NF),第三范式(3NF). 第一范式(1NF) 第一范式其实是关系型数据库的基础,即任何关系型数据

  • MySQL约束与索引概念详解

    目录 一.关系型数据库设计规则 二.数据完整性和约束与索引的概念 三.约束的应用 一.关系型数据库设计规则 遵循ER模型和三范式 E entity 代表实体的意思 对应到数据库当中的一张表 R relationship 代表关系的意思 三范式: 1.列不能拆分 2.唯一标识 3.关系引用主键 具体体现 将数据放到表中,表再放到库中. 一个数据库中可以有多个表,每个表都有一个名字,用来标识自己.表名具有唯一性. 表具有一些特性,这些特性定义了数据在表中如何存储,类似java和python 中 “类

  • mysql数据存储过程参数实例详解

    MySQL 存储过程参数有三种类型:in.out.inout.它们各有什么作用和特点呢? 一.MySQL 存储过程参数(in) MySQL 存储过程 "in" 参数:跟 C 语言的函数参数的值传递类似, MySQL 存储过程内部可能会修改此参数,但对 in 类型参数的修改,对调用者(caller)来说是不可见的(not visible). drop procedure if exists pr_param_in; create procedure pr_param_in ( in id

  • redhat7.1 安装mysql 5.7.10步骤详解(图文详解)

    在redhat下安装MySQL,步骤如下 Mysql目录安装位置:/usr/local/mysql 数据库保存位置:/data/mysql 日志保存位置:/data/log/mysql 下载安装包 http://downloads.mysql.com/archives/community/ 1. 获取mysql安装包,mysql-5.7.10-Linux-glibc2.5-x86_64.tar解压后目录如下. 2. 解压mysql-5.7.10-linux-glibc2.5-x86_64.tar

  • mysql 的replace into实例详解

    mysql 的replace into实例详解 replace into 跟 insert 功能类似,不同点在于:replace into 首先尝试插入数据到表中. 1.如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据. 2. 否则,直接插入新数据. 要注意的是:插入数据的表必须有主键或者是唯一索引!否则的话,replace into 会直接插入数据,这将导致表中出现重复的数据.  MySQL中replace into有三种写法: 代码如下: replac

  • PHP和MYSQL实现分页导航思路详解

    预期效果 思路 通过SQL语句 SELECT * FROM table LIMIT start end 来从MySql数据库 步骤 传入页码p: 根据页码获取数据php->mysql 显示数据+分页条 源码 github 链接 注意点 table,input,button等控件的样式不会继承body,需要重新定义如下 input,label, select,option,textarea,button,fieldset,legend,table{ font-size:18px; FONT-FAM

  • CentOS 6.6 源码编译安装MySQL 5.7.18教程详解

    一.添加用户和组 1.添加mysql用户组 # groupadd mysql 2.添加mysql用户 # useradd -g mysql -s /bin/nologin mysql -M 二.查看系统中是否安装mysql,如果安装需要卸载 # rpm -qa | grep mysql mysql-libs-5.1.73-3.el6_5.x86_64 # rpm -e mysql-libs-5.1.73-3.el6_5.x86_64 --nodeps 三.安装所需依赖包 # yum -y ins

  • MySQL对中文进行排序详解及实例

    MySQL对中文进行排序详解 MySQL默认只支持对日期.时间和英文字符串进行排序,如果对中文进行order by很可能得不到想要的结果,如下面的查询并不会按我们所想的根据汉字的拼音进行排序: SELECT * from user order by user_name; 如果相对中文进行排序的话,可以使用CONVERT(coloum_name USING GBK)将中文转为GBK编码形式,然后再排序,就可以实现根据汉子的拼音进行排序: SELECT * from user order by CO

  • MySQL binlog 远程备份方法详解

    以前备份binlog时,都是先在本地进行备份压缩,然后发送到远程服务器中.但是这其中还是有一定风险的,因为日志的备份都是周期性的,如果在某个周期中,服务器宕机了,硬盘损坏了,就可能导致这段时间的binlog就丢失了. 而且,以前用脚本对远程服务器进行备份的方式,有个缺点:无法对MySQL服务器当前正在写的二进制日志文件进行备份.所以,只能等到MySQL服务器全部写完才能进行备份.而写完一个binlog的时间并不固定,这就导致备份周期的不确定. 从MySQL5.6开始,mysqlbinlog支持将

  • MySQL交换分区的实例详解

    MySQL交换分区的实例详解 前言 在介绍交换分区之前,我们先了解一下 mysql 分区. 数据库的分区有两种:水平分区和垂直分区.而MySQL暂时不支持垂直分区,因此接下来说的都是水平分区.水平分区即:以行为单位对表进行分区.比如:按照时间分区,每一年一个分区等. 在MySQL中,分区是可以交换的,可以将一个分区表中的一个分区和一个普通表中的数据互换. 交换分区的实现 1.交换分区的语法 alter table pt exchange partition p with table nt; 解释

随机推荐