数据库设计三范式

简介: 数据库三范式是设计合理表结构的指导原则。第一范式要求字段原子性,不可再分;第二范式要求消除部分依赖,一张表只描述一件事;第三范式要求消除传递依赖。虽为优化数据冗余、更新异常等问题,但实际应用中需结合业务权衡,不必严格拘泥。

第一范式 - 1NF
遵循原子性。即,表中字段的数据,不可以再拆分。先看一个不符合第一范式的表结构,如下:
员工编码 姓名 年龄
001 销售部小张 28
002 运营部小黄 25
003 技术部小高 22
在这一个表中的,姓名 字段下的数据是可以再进行拆分的,因此它不符合第一范式,那怎么样才符合第一范式呢?如下:
员工编码 部门 姓名 年龄
001 销售部 小张 28
002 运营部 小黄 25
003 技术部 小高 22
那是否遵循第一范式就一定是好的呢?如下:
员工编码 姓名 地址
001 小张 江西省南昌市东湖区
002 小黄 广东省佛山市禅城区
003 小高 湖北省武汉市新洲区
通过观察上述表结构,我们发现,地址是可以再进一步拆分的,比如:
员工编码 姓名 省 市 区
001 小张 江西省 南昌市 东湖区
002 小黄 广东省 佛山市 禅城区
003 小高 湖北省 武汉市 新洲区
虽然拆分后,看上去更符合第一范式了,但是如果项目就只需要我们输出一个完整地址呢?那明显是表在没拆分的时候会更好用。所以范式只是给了我们一个参考,我们更多的是要根据项目实际情况设计表结构。
第二范式 - 2NF
在满足第一范式的情况下,遵循唯一性,消除部分依赖。即,表中任意一个主键或任意一组联合主键,可以确定除该主键外的所有的非主键值。再通俗点讲就是,一个表只能描述一件事情。我们用一个经典案例进行解析。
学号 姓名 年龄 课程名称 成绩 学分
001 小张 28 语文 90 3
001 小张 28 数学 90 2
002 小黄 25 语文 90 3
002 小黄 25 语文 90 3
003 小高 22 数学 90 2
我们先分析一下表结构。

  1. 假设学号是表中的唯一主键,那由学号就可以确定姓名和年龄了,但是却不能确定课程名称和成绩。
  2. 假设课程名称是表中的唯一主键,那由课程名称就可以确定学分了,但是却不能确定姓名、年龄和成绩。
  3. 虽然通过学号和课程名称的联合主键,可以确定除联合主键外的所有的非主键值,但是基于上述两个假设,也不符合第二范式的要求。

那我们应该如何调整表结构,让它能复合第二范式的要求呢?
我们可以基于上述的三种主键的可能,拆分成 3 张表,保证一张表只描述一件事情。

  1. 学生表 - 学号做主键
    学号 姓名 年龄
    001 小张 28
    002 小黄 25
    003 小高 22
  2. 课程表 - 课程名称做主键
    课程名称 学分
    语文 3
    数学 2
  3. 成绩表 - 学号和课程名称做联合主键
    学号 课程名称 成绩
    001 语文 90
    001 数学 90
    002 语文 90
    002 语文 90
    003 数学 90
    这时候我们可能会想,为什么我们就要遵循第二范式呢?不遵循第二范式会造成什么样的后果呢?
  4. 造成整表的数据冗余。
    如学生表,可能我就只有2个学生,每个学生都有许多的信息,比如,年龄、性别、身高、住址......如果与课程信息放到同一张表中,可能每个学生有3门课程,那数据总条数就会变成6条了。但是通过拆分,学生表我们只需要存储 2 条学生信息,课程表只需要存储 3 条课程信息,成绩表就只需保留学号、课程名称和成绩字段。
  5. 更新数据不方便。
    假设,课程的学分发生了变更,那我们就需要把整表关于该课程的学分都要更新一次,但如果我们拆分出课程表,那我们就只需要把课程表中的课程信息更新就行。
  6. 插入数据不方便或产生异常。
    ① 假设主键是学号或课程名称,我们新增了某个课程,需要把数据插入到表中,这时,可能只有部分人有选修这门课程,那我们插入数据的时候还要规定给哪些人插入对应的课程信息,同时可能由于成绩还没有,我们需要对成绩置空,后续有成绩后还得重新更新一遍。
    ② 假设主键是学号和课程名称的联合主键。同样也是新增了某课程,但是暂时没有人选修这门课,缺少了学号主键字段数据,会导致课程信息无法插入。
    第三范式 - 3NF
    在满足第二范式的情况下,消除传递依赖。即,在任一主键都可以确定所有非主键字段值的情况下,不能存在某非主键字段 A 可以获取 某非主键字段 B。
    仍然用一个经典例子来解析
    学号 姓名 班级 班主任
    001 小黄 一年级(1)班 高老师
    这个表中,学号是主键,它可以唯一确定姓名、班级、班主任,符合了第二范式,但是在非主键字段中,我们也可以通过班级推导出该班级的班主任,所以它是不符合第三范式的。
    那怎么设计表结构,才是符合第三范式的呢?
  7. 学生表
    学号 姓名 班级
    001 小黄 一年级(1)班
  8. 班级表
    班级 班主任
    一年级(1)班 高老师
    通过把班级与班主任的映射关系另外做成一张映射表,我们就成功地消除了表中的传递依赖了。
    总结
    不知道读者们有没有发现,以上所介绍的范式的最终目的都是为了减少我们的工作量呢?所以说,尽管范式是一种很好的指导规范,但在实际应用中,我们也不需要太局限在范式中,更多的是应该从项目中出发,设计出合理的表结构。
    以下是本篇三范式的简单总结:
    ● 第一范式(1 NF):字段不可再拆分。
    ● 第二范式(2 NF):表中任意一个主键或任意一组联合主键,可以确定除该主键外的所有的非主键值。
    ● 第三范式(3 NF):在任一主键都可以确定所有非主键字段值的情况下,不能存在某非主键字段 A 可以获取 某非主键字段 B。
相关文章
|
4月前
|
存储 负载均衡 算法
负载均衡算法
本文介绍了多种负载均衡算法:随机、加权随机、轮询、加权轮询、最小活跃数、源地址哈希及一致性哈希。适用于不同场景,如性能均等或差异服务器、需保持会话一致等,提升系统稳定性与负载能力。
|
4月前
|
人工智能 运维 监控
电力行业RPA案例大全:从保供到服务,数字员工如何重塑电网?
2024年川渝高温,国网四川电力借助15个RPA“数字员工”,实现停电巡查、过载预警全自动,故障响应提速近40%。从发电到配电、营销与管理,RPA正重塑电力行业,让基层工作从“手忙脚乱”走向“从容不迫”,成为数字化转型的核心引擎。
491 1
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
构建AI智能体:九十、图解大模型核心三大件 — 输入编码、注意力机制与前馈网络层
本文深入解析了大模型三大核心技术:输入编码、多头自注意力机制和前馈网络层,从应用视角阐述了它们的工作原理和协同效应。输入编码负责将文本转换为富含语义和位置信息的数学表示;多头自注意力机制通过多专家团队模式建立全局依赖关系,解决长距离依赖问题;前馈网络层则通过非线性变换进行深度语义消歧。文章通过可视化示例展示了词向量的语义关系建模、注意力权重的分布模式以及前馈网络的语义过滤功能,形象地说明了大模型如何通过这三层架构实现"广泛联系-深度加工"的认知过程。
276 5
|
3月前
|
监控 搜索推荐 物联网
一文读懂LoRA微调原理:大模型高效适配的核心逻辑
通过冻结大模型参数、仅训练少量低秩矩阵,实现高效微调:成本低、周期短、不破坏通用能力。适配医疗、金融等垂直场景,支持多任务复用与边缘部署,成为大模型落地首选技术。
一文读懂LoRA微调原理:大模型高效适配的核心逻辑
|
4月前
|
数据采集 人工智能 监控
构建AI智能体:七十七、AI古典文学:基于LoRA微调Qwen1.5-0.5B打造唐诗生成器
本文介绍了基于LoRA微调技术实现AI创作唐诗的方法。通过使用Qwen1.5-0.5B-Chat作为基础模型,仅调整0.34%的参数(157万),在CPU上39分钟即可完成训练。文章详细展示了从模型选择、28首原创唐诗数据集构建、LoRA参数配置到训练评估的全过程。实验结果表明,模型能生成符合主题的原创唐诗,但在格律平仄、意境深度等方面仍需优化。这一实践验证了LoRA技术在古典文学创作领域的可行性,为轻量化AI创作提供了有价值的参考。
587 16
|
3月前
|
设计模式 人工智能 架构师
从模块到良好:如何设计一个生产级的Agent架构?
本文探讨生产级Agent架构设计,涵盖感知、决策、记忆与执行四大核心模块,强调分层解耦、多Agent协同及确定性保护、状态一致性等非功能性约束,助力AI系统从“代码驱动”迈向“意图驱动”。
1213 3
|
4月前
|
IDE 开发工具 C++
Python 初学者常见 10 大误区与避坑指南
本文总结Python初学者易犯的10大编码误区,如缩进错误、混淆“==”与“is”、修改迭代列表等,结合典型案例解析原因并提供实用解决方案,帮助新手规避常见陷阱,建立正确的Python编程思维,提升代码质量与可读性。
|
5月前
|
机器学习/深度学习 人工智能 物联网
大模型微调有必要做吗?全参数微调、LoRA还是RAG?看完这篇你就懂了
在人工智能时代,若想以最小成本、最高效率赋能通用大模型专业的行业能力,关键在于找到效果、成本与灵活性的黄金平衡点......
751 5
大模型微调有必要做吗?全参数微调、LoRA还是RAG?看完这篇你就懂了
|
4月前
|
存储 缓存 Java
SpringBoot自动装配机制
本章深入解析SpringBoot自动装配机制,从@SpringBootApplication注解入手,剖析其组合注解原理。重点讲解@EnableAutoConfiguration如何通过@AutoConfigurationPackage实现包扫描、通过AutoConfigurationImportSelector加载spring.factories中的自动配置类,结合@Conditional条件注解实现智能化配置。同时解析@ComponentScan组件过滤机制及自定义排除方式,揭示SpringBoot“约定优于配置”的底层实现逻辑。(238字)

热门文章

最新文章