数据库三范式简单理解

article/2025/10/17 8:06:37

数据库设计当中三范式是经常遇到的,如果实际项目数据库设计中能达到第三范式基本也就满足要求了,那么如何快速有效的理解三个范式,同时应用于实际项目中去呢?

首先看看标准定义的三个范式:

第一范式(1NF)

所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。

在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。

我的理解:列不可分。

第二范式(2NF)

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一的区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。要求实体的属性完全依赖于主关键字。

我的理解:不能部分依赖。即:一张表存在组合主键时,其他非主键字段不能部分依赖。

第三范式(3NF)

 满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。

我的理解:不能存在传递依赖。即:除主键外,其他字段必须依赖主键。

官方标准的定义,我个人感觉说得非常术语化,比较难以理解消化。我简单的理解为三句话,非常简短,比较好理解。如果各位路过朋友们,有更好理解的总结,请不吝指出!


二,,

1.第一范式(确保每列保持原子性)

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式,如下表所示。

上表所示的用户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。

                

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

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

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

 订单信息表

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

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

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

                 

3.第三范式(确保每列都和主键列直接相关,而不是间接相关)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。

这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输入客户信息的内容,减小了数据冗余。



三,,,

sql sever 中如何在两个表之间建立参照关系
这个是通过创建一种称为   “外键”  的东西, 来建立  参照关系的。



例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
-- 创建测试主表. ID 是主键.
CREATE  TABLE  test_main (
   id       INT    NOT  <a href= "https://www.baidu.com/s?wd=NULL&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWPWczPH0vnhnYmW6vrHD40ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DdnH0knjmsPWR3PHb4PWc3PW0"  target= "_blank"  class= "baidu-highlight" > NULL </a>,
   value   <a href= "https://www.baidu.com/s?wd=VARCHAR&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWPWczPH0vnhnYmW6vrHD40ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DdnH0knjmsPWR3PHb4PWc3PW0"  target= "_blank"  class= "baidu-highlight" > VARCHAR </a>(10),
   PRIMARY  <a href= "https://www.baidu.com/s?wd=KEY&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWPWczPH0vnhnYmW6vrHD40ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DdnH0knjmsPWR3PHb4PWc3PW0"  target= "_blank"  class= "baidu-highlight" > KEY </a>(id)  
);
-- 创建测试子表. 
CREATE  TABLE  test_sub (
   id       INT   NOT  <a href= "https://www.baidu.com/s?wd=NULL&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWPWczPH0vnhnYmW6vrHD40ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DdnH0knjmsPWR3PHb4PWc3PW0"  target= "_blank"  class= "baidu-highlight" > NULL </a>,
   main_id  INT  ,
   value   <a href= "https://www.baidu.com/s?wd=VARCHAR&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWPWczPH0vnhnYmW6vrHD40ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DdnH0knjmsPWR3PHb4PWc3PW0"  target= "_blank"  class= "baidu-highlight" > VARCHAR </a>(10),
   PRIMARY  <a href= "https://www.baidu.com/s?wd=KEY&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWPWczPH0vnhnYmW6vrHD40ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DdnH0knjmsPWR3PHb4PWc3PW0"  target= "_blank"  class= "baidu-highlight" > KEY </a>(id)  
);
-- 插入测试主表数据.
INSERT  INTO  test_main(id, value)  VALUES  (1,  'ONE' );
INSERT  INTO  test_main(id, value)  VALUES  (2,  'TWO' );
-- 插入测试子表数据.
INSERT  INTO  test_sub(id, main_id, value)  VALUES  (1, 1,  'ONEONE' );
INSERT  INTO  test_sub(id, main_id, value)  VALUES  (2, 2,  'TWOTWO' );
下面这个语句,  在  主表与子表之间, 创建一个关系
ALTER  TABLE  test_sub  ADD  CONSTRAINT  main_id_cons   FOREIGN  <a href= "https://www.baidu.com/s?wd=KEY&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWPWczPH0vnhnYmW6vrHD40ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DdnH0knjmsPWR3PHb4PWc3PW0"  target= "_blank"  class= "baidu-highlight" > KEY </a> (main_id)   REFERENCES   test_main;


四,,举个例子

请问,如何将如图所示的这张数据库表分割成符合第三范式(3NF)的几张表?




用户,学院,专业,年级,班级
用户(用户编号userid,用户名username,密码password,性别sex,权限authority,班级编号classid),主键是userid,外键是classid
学院(学院编号collegeid,学院名称college),主键是collegeid
专业(专业编号specialtyid,专业名称specialty,方向direction,学院编号collegeid),主键是specialtyid,外键是collegeid
年级(年级编号gradeid,年级名称grade),主键是gradeid
班级(班级编号classid,班级名称class,专业编号specialtyid,辅导员mother,班长monitor,年级编号gradeid),主键是classid,外键是专业编号specialtyid,辅导员mother(参照userid),班长monitor(参照userid),年级编号gradeid
五,,,好处
数据库的三范式对数据库来说是是具有一定好处的,先抛开定义不谈,每当设计数据库的时候,往往会具有较大的数据库体系,也就是每个表之间的关系,不同表中某些属性都具有一定的关系,因为具有关联,所以数据在存储的时候逻辑会比较复杂,如果不按照一定的规则来存储数据就会有乱子,就像你开车一样,没有交通规则不就混乱了么?因此,在数据库设计的时候满足范式要求可以很大限度的合理的处理数据,减少数据的冗余,即多余的用数据,当然范式的优点也不仅仅体现在这方面。
但换句话说,如果在某些特定的情况下还死死遵循范式也是不可取的,因为可能降低数据库的效率,数据库的设计应该根据当前情况和需求做出灵活的处理。

http://chatgpt.dhexx.cn/article/x0MtRfWi.shtml

相关文章

数据库三大范式

数据库三大范式 数据库的设计范式是数据库设计所需要满足的规范&#xff0c;满足这些规范的数据库是简洁的、结构明晰的&#xff0c;同时&#xff0c;不会发生插入&#xff08;insert&#xff09;、删除&#xff08;delete&#xff09;和更新&#xff08;update&#xff09;操…

数据库三范式3NF指什么?

三范式面试的时候问的比较多&#xff0c;概念需要了解下&#xff1a; 数据库设计三大范式 为了建立冗余较小、结构合理的数据库&#xff0c;设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系…

数据库的三范式详细解释

1.定义 三范式是数据库的规范化的内容&#xff0c;所谓的数据库三范式通俗的讲就是设计数据库表所应该遵守的一套规范&#xff0c;如果不遵守就会造成设计的数据库不规范&#xff0c;出现数据库字段冗余&#xff0c;数据的查询&#xff0c;插入等操作等问题。 注意&#xff1a;…

数据库三范式是什么?(3NF详解)

什么是范式&#xff1f; 范式是数据库设计时遵循的一种规范&#xff0c;不同的规范要求遵循不同的范式。 最常用的三大范式 第一范式(1NF)&#xff1a;属性不可分割&#xff0c;即每个属性都是不可分割的原子项。(实体的属性即表中的列) 第二范式(2NF)&#xff1a;满足第一…

数据库三范式【看了就有收获,最简单的例子解释】

1. 数据库的三范式是什么&#xff1f;&#xff1f;&#xff1f;&#xff1f; 范式规范&#xff0c;原则上是必须遵循的&#xff08;但是需求不同可以不遵循&#xff09;&#xff0c;特殊情况可以不遵循 第一范式&#xff08;1NF&#xff09;&#xff1a;符合数据表的原子性【…

Java面试题之数据库三范式是什么?

什么是范式&#xff1f; 简言之就是&#xff0c;数据库设计对数据的存储性能&#xff0c;还有开发人员对数据的操作都有莫大的关系。所以建立科学的&#xff0c;规范的的数据库是需要满足一些规范的来优化数据数据存储方式。在关系型数据库中这些规范就可以称为范式。 什么是三…

数据库的三大范式

1.为什么需要数据库设计2.范式(Normal Formal&#xff09;2.1范式概述2.2键和相关属性的概念2.3第一范式(1NF)2.4第二范式(2NF&#xff09;2.5第三范式(3NF&#xff09;2.6范式的优缺点 3.反范式化3.1概述3.2 反范式的新问题3.3反范式的适用场景 4.BCNF(巴斯范式) 文章是看尚硅…

数据库设计的三范式超详细详解

目录 写在前面 第一范式&#xff08;1NF&#xff09;&#xff1a;原子性&#xff08;存储的数据应该具有“不可再分性”&#xff09; 第二范式&#xff08;2NF&#xff09;&#xff1a;唯一性 (消除非主键部分依赖联合主键中的部分字段)&#xff08;一定要在第一范式已经满足…

FarPoint.Win.Spread 自定义表头

软件开发技术交流&#xff0c;同学习共进步&#xff0c;欢迎加群&#xff0c; 群号:169600532 最近C/S项目中用到FarPoint.Win.Spread&#xff0c;想在表头加个全选的checkbox&#xff0c;实现效果如图&#xff1a; 列的设置大家都清楚&#xff0c;直接可视化视图中设置该列Ce…

关于 farpoint spread的问题。

由于万不得已&#xff0c;使用了 farpoint spread 控件。 版本&#xff1a;4.0.3509.2008 天杀&#xff0c;这东西在网上居然没有可以用的使用说明&#xff0c;欺负不会英文的我。 1.farpoint spread 单元格内增加滚动条。 虽然简单&#xff0c;但是如果忽略一个参数设置就会…

WPF方便的调用FarPoint

一、安装FarPoint 二、创建WPF项目 三、引用farpoint相关dll 四、引用winform的相关dll: System.Windows.Forms.dll 五、引用winfrom与WPF的窗台整合dll 所需dll截图 六、新建一个winfrom用户控件&#xff0c;使用farpoint创建一个表格 通过右键spread design可以直接使…

N-Gram 分词算法 Python 实现

概述 N-Gram 算法是一种单词级别的窗口取词算法&#xff0c;N-Gram&#xff08;有时也称为N元模型&#xff09;是自然语言处理中一个非常重要的概念&#xff0c;通常在NLP中&#xff0c;人们基于一定的语料库&#xff0c;可以利用N-Gram来预计或者评估一个句子是否合理。另外一…

ElasticSearch学习随笔之分词算法

ElasticSearch 1、ElasticSearch学习随笔之基础介绍 2、ElasticSearch学习随笔之简单操作 3、ElasticSearch学习随笔之java api 操作 4、ElasticSearch学习随笔之SpringBoot Starter 操作 5、ElasticSearch学习随笔之嵌套操作 6、ElasticSearch学习随笔之分词算法 7、ElasticS…

常用分词算法笔记

常用统计语言模型&#xff0c;包括了N元文法统计模型&#xff08;N-gram Model&#xff09;、隐马尔科夫模型&#xff08;Hidden Markov Model&#xff0c;简称HMM&#xff09;、最大熵模型&#xff08;Maximum Entropy Model&#xff09;。 N-Gram这是一种依赖于上下文环境的词…

NLP 中文分词-双向匹配算法(理论+Python实现)

一、理论描述 1.中文分词的概念&#xff1a; 是指把没有明显分界标志的字串切分为词串&#xff0c;包括标点符号、数字、数学符号、各种标记、人名、地名、机构名等未登录词的识别。汉语自动分词主要包括&#xff1a;&#xff08;1&#xff09;根据分词规范&#xff0c;建立机…

NLP ---分词详解(常见的五种分词技术二)

上一篇我们讲了N一最短路径方法、基于词的n元文法模型&#xff0c;本节将主要介绍由字构词方法、基于词感知机算法的汉语分词方法、基于字的生成模型和区分式模型相结合的汉语分词方法&#xff0c;下面我们就开始讲解由字构词的方法&#xff1a; 由字构词方法 由字构词方法的…

常用分词算法总结(字典、统计、神经网络)

本文转载自公众号“夕小瑶的卖萌屋”&#xff0c;专业带逛互联网算法圈的神操作 -----》我是传送门 关注后&#xff0c;回复以下口令&#xff1a; 回复【789】 &#xff1a;领取深度学习全栈手册&#xff08;含NLP、CV海量综述、必刷论文解读&#xff09; 回复【入群】&#xf…

分词算法----正向和逆向最大匹配算法(含Python代码实现)

文章目录 分词算法(Segmentation Method)最大匹配算法(Maximum Matching)需要的前提正向最大匹配算法(Forwards Maximum Match&#xff0c;FMM)逆向最大匹配算法(Reverse Maximum Match&#xff0c;RMM)双向最大匹配算法小结 分词算法(Segmentation Method) 在文本处理流程中&…

自然语言处理——分词算法

引言 分词是自然语言处理中的基本操作&#xff0c;今天我们就来看一下常用的分词算法及实现。 最大匹配算法 所谓的最大匹配指的是匹配最长的单词&#xff0c;通常会指定一个最大长度。根据搜索顺序的不同&#xff0c;主要有前向最大匹配算法、后向最大匹配算法、双向匹配算…

分词算法介绍——千里之行,始于足下

NLP&#xff08;自然语言处理&#xff09;&#xff0c;对于它来说&#xff0c;如何有效地编码一段文本&#xff0c;是它首先要考虑的问题。而在编码文本之前&#xff0c;要先把它切割成小块&#xff0c;这些小块叫做 tokens&#xff0c;这个过程叫做分词&#xff08;tokenizati…