数据库三范式的简单理解

参考书籍:数据库系统概论第四版-王珊、萨师煊
数据库范式
范式的级别
      设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
      目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
      范式越高,冗余最低,一般到三范式,再往上,表越多,可能导致查询效率下降。所以有时为了提高运行效率,可以让数据冗余(反三范式,一般某个数据经常被访问时,比如数据表里存放了语文数学英语成绩,但是如果在某个时间经常要得到它的总分,每次都要进行计算会降低性能,可以加上总分这个冗余字段)。
      后面的范式是在满足前面范式的基础上,比如满足第二范式的一定满足第一范式。
第一范式(1NF):确保每一列的原子性
如果每一列都是不可再分的最小数据单元,则满足第一范式。

id
地址
1
中国广东
2
中国云南
上面的表地址字段其实可以继续分:

id
国家
省份
1
中国
广东
2
中国
云南
但是具体地址到底要不要拆分 还要看具体情形,比如看看将来会不会按国家或者省市进行分类汇总或者排序,如果需要,最好就拆,如果不需要而仅仅起字符串的作用,可以不拆,操作起来更方便。
第二范式:非键字段必须依赖于键字段
如果一个关系满足1NF,并且除了主键以外的其它列,都依赖与该主键,则满足二范式(2NF),第二范式要求每个表只描述一件事。
例如:

字段
例子
订单编号
001
产品编号
a011
订购日期
2017-4-8
价格
¥30
而实际上,产品编号与订单编号并没有明确的关系,订购日期与订单编号有关系,因为一旦订单编号确定下来了,订购日期也确定了,价格与订单编号也没有直接关系,而与产品有关,所以上面的表实际上可以拆分:
订单表:

订单编号
001
日期
2017-4-8

产品表:

产品编号
a011
价格
¥30
第三范式:在1NF基础上,除了主键以外的其它列都不传递依赖于主键列,或者说: 任何非主属性不依赖于其它非主属性
(在2NF基础上消除传递依赖)
例如:

字段
例子
订单编号
001
订购日期
2017-4-8
顾客编号
a01
顾客姓名
howard
上面的满足第一和第二范式,但是不满足第三范式,原因如下:
通过顾客编号可以确定顾客姓名,通过顾客姓名可以确定顾客编号,即在这个订单表里,这两个字段存在传递依赖,只需要一个就够了。
又如:

主键
学号
姓名
成绩
1
111
howard
90
2
222
tom
90

上面的表,学号和姓名存在传递依赖,因为(学号,姓名)->成绩,学号->成绩,姓名->成绩。所以学号和姓名有一个冗余了,只需要保留一个。
<think>好的,我现在需要详细解释数据库三范式及其应用场景。首先,用户已经提供了一些参考资料,我需要仔细阅读这些引用内容,确保准确理解每个范式的定义和目的。同时,用户要求使用中文回答,并且符合特定的格式要求,比如行内数学表达式用$...$,独立公式用$$...$$,不过根据引用内容,可能数学公式较少,但需要注意LaTeX语法的正确性。 首先,我需要明确三范式的每个级别: 第一范式(1NF)要求每个字段都是不可分割的原子值。比如,地址字段不能包含省、市、区等多个信息,而应拆分成多个字段。引用[1]和[2]都提到了这一点,我需要确认是否正确。 第二范式(2NF)在满足1NF的基础上,消除非主属性对候选码的部分函数依赖。这意味着每个非主属性必须完全依赖于主键,而不是部分依赖。例如,订单详情表中,如果主键是订单ID和产品ID,那么其他字段如产品数量应完全依赖于这两个字段,而不是仅依赖其中一个。引用[1]、[2]和[5]可能对此有描述,需要核对。 第三范式(3NF)在满足2NF的基础上,消除非主属性之间的传递依赖。即非主属性必须直接依赖于主键,不能通过其他非主属性间接依赖。例如,学生表中包含学号、学院和院长,如果院长依赖于学院,而学院依赖于学号,那么院长就传递依赖于学号,这不符合3NF,需要拆分。引用[1]、[3]、[4]和[5]应该提到了这点。 应用场景方面,需要说明何时应该遵循范式,何时可以反范式。引用[3]和[4]提到,高范式可能降低查询效率,因为需要更多的JOIN操作,因此在读多写少或性能要求高的情况下,可能采用反范式设计,增加冗余字段。例如,在用户信息表中,如果经常需要查询用户名和头像,可以在多个表中冗余这些字段,避免频繁关联用户表。 同时,需要确保回答结构清晰,分点解释每个范式,给出示例,然后讨论应用场景和反范式的权衡。还要注意引用标记的正确添加,例如在提到消除数据冗余时引用[1],在讨论查询效率时引用[3]和[4]。 接下来,检查是否有遗漏点,比如每个范式的优缺点,以及它们解决的问题。例如,1NF解决数据原子性问题,2NF解决部分依赖带来的冗余,3NF解决传递依赖的问题。同时,反范式设计可能带来的数据冗余和潜在的一致性问题,如更新异常,但提升查询性能。 最后,生成相关问题,要确保问题与三范式相关,并且覆盖概念、应用、优缺点等方面。例如,如何判断是否符合某个范式,反范式的具体例子,范式与性能的权衡等。 现在需要组织内容,确保符合用户的格式要求,正确使用引用标记,语言简洁明了,结构清晰。同时,避免使用Markdown格式,但根据用户提供的示例,可能需要使用代码块来展示示例,比如表格结构。不过用户示例中的代码块是Python,这里可能需要用SQL示例,但根据引用内容,是否有必要?例如,引用[4]提到反范式化的例子,如增加冗余字段,可以用一个用户表和订单表中冗余用户名的例子。 总结步骤: 1. 分点介绍三范式,每个范式的定义、示例、解决的问题。 2. 应用场景:何时遵循范式,何时反范式。 3. 优缺点对比。 4. 相关问题生成。</think>### 数据库三范式详解及应用场景 #### 一、三范式定义与作用 1. **第一范式(1NF)** - **定义**:字段是原子的、不可再分的。 - **示例**:若用户表包含字段$(\text{地址})$存储“北京市海淀区”,需拆分为$(\text{省})$、$(\text{市})$、$(\text{区})$。 - **作用**:消除重复数据存储,避免查询复杂度[^1]。 2. **第二范式(2NF)** - **定义**:在满足1NF的基础上,消除非主属性对候选码的**部分函数依赖**。 - **示例**:订单详情表中,若主键为$(\text{订单ID}, \text{产品ID})$,但$(\text{产品价格})$仅依赖$\text{产品ID}$,则需拆分为订单表和产品表[^2]。 - **作用**:解决数据冗余和更新异常(如修改产品价格需更新多条记录)[^5]。 3. **第三范式(3NF)** - **定义**:在满足2NF的基础上,消除非主属性间的**传递依赖**。 - **示例**:学生表中,若$\text{学号} \rightarrow \text{学院} \rightarrow \text{院长}$,需拆分为学生表和学院表[^3]。 - **作用**:进一步减少冗余,避免因间接依赖导致的数据不一致[^1]。 #### 二、应用场景与权衡 1. **遵循范式的场景** - **事务型系统(OLTP)**:如银行系统,需频繁插入、更新数据,范式设计可减少冗余并保证一致性。 - **数据规范性要求高**:如政府档案管理,需避免数据重复和歧义[^1]。 2. **反范式化的场景** - **分析型系统(OLAP)**:如报表统计,通过冗余字段减少多表关联,提升查询效率[^4]。 - **高并发读场景**:如电商首页展示商品信息,冗余商品名称、价格到订单表,避免频繁JOIN。 #### 三、优缺点对比 | **范式级别** | **优点** | **缺点** | |--------------|----------------------------|------------------------------| | 高范式(3NF)| 数据冗余少,更新效率高 | 查询需多表关联,性能可能下降 | | 反范式 | 查询速度快,结构简单 | 数据冗余,需维护一致性 | #### 四、示例:反范式设计 ```sql -- 用户表(范式设计) CREATE TABLE user ( user_id INT PRIMARY KEY, username VARCHAR(50), avatar_url VARCHAR(100) ); -- 订单表(反范式设计:冗余用户名和头像) CREATE TABLE order ( order_id INT PRIMARY KEY, user_id INT, username VARCHAR(50), -- 冗余字段 avatar_url VARCHAR(100), -- 冗余字段 amount DECIMAL ); ``` 此设计避免查询订单时频繁关联用户表,但需通过触发器或应用层保证冗余字段一致性。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值