当前位置: 首页 > news >正文

mysql 范式化_Mysql范式与反范式

第一范式(1NF)

第一范式,强调属性的原子性约束,要求属性具有原子性,不可再分解。

举个例子:活动表(活动编码,活动名称,活动地址),假设这个场景中,活动地址可以细分为国家、省份、城市、市区、位置,那么就没有达到第一范式。

第二范式(2NF)

第二范式,强调记录的唯一性约束,表必须有一个主键,并且没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

举个例子:版本表(版本编码,版本名称,产品编码,产品名称),其中主键是(版本编码,产品编码),这个场景中,数据库设计并不符合第二范式,因为产品名称只依赖于产品编码。存在部分依赖。所以,为了使其满足第二范式,可以改造成两个表:版本表(版本编码,产品编码)和产品表(产品编码,产品名称)。

第三范式(3NF)

第三范式,强调属性冗余性的约束,即非主键列必须直接依赖于主键。

举个例子,订单表(订单编码,顾客编码,顾客名称),其中主键是(订单编码),这个场景中,顾客编码、顾客名称都完全依赖于主键,因此符合第二范式,但是顾客名称依赖于顾客编码,从而间接依赖于主键,所以不能满足第三范式。为了使其满足第三范式,可以拆分两个表:订单表(订单编码,顾客编码)和顾客表(顾客编码,顾客名称),拆分后的数据库设计,就可以完全满足第三范式的要求了。

值得注意的是,第二范式的侧重点是非主键列是否完全依赖于主键,还是依赖于主键的一部分。第三范式的侧重点是非主键列是直接依赖于主键,还是直接依赖于非主键列。

反范式

范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦。 然而,通过数据库范式化设计,将导致数据库业务涉及的表变多,并且可能需要将涉及的业务表进行多表连接查询,这样将导致性能变差,且不利于分库分表。因此,出于性能优先的考量,可能在数据库的结构中需要使用反范式的设计,即空间换取时间,采取数据冗余的方式避免表之间的关联查询。至于数据一致性问题,因为难以满足数据强一致性,一般情况下,使存储数据尽可能达到用户一致,保证系统经过一段较短的时间的自我恢复和修正,数据最终达到一致。

需要谨慎使用反模式设计数据库。一般情况下,尽可能使用范式化的数据库设计,因为范式化的数据库设计能让产品更加灵活,并且能在数据库层保持数据完整性。

有的时候,提升性能最好的方法是在同一表中保存冗余数据,如果能容许少量的脏数据,创建一张完全独立的汇总表或缓存表是非常好的方法。举个例子,设计一张“下载次数表”来缓存下载次数信息,可使在海量数据的情况下,提高查询总数信息的速度。

另外一个比较典型的场景,出于扩展性考虑,可能会使用 BLOB 和 TEXT 类型的列存储 JSON 结构的数据,这样的好处在于可以在任何时候,将新的属性添加到这个字段中,而不需要更改表结构。但是,这个设计的缺点也比较明显,就是需要获取整个字段内容进行解码来获取指定的属性,并且无法进行索引、排序、聚合等操作。因此,如果需要考虑更加复杂的使用场景,更加建议使用 MongoDB 这样的文档型数据库。

真实场景很难做到范式化,一般会选择性能,保证最终一致性。

相关文章:

  • jsp ssh mysql是什么_JSP+SSH+Mysql实现的学生管理系统
  • MySQL备机比主机binlog大_关于PostgreSQL流复制的延迟
  • python tempfile模块用不了_Python tempfile模块和线程表现不佳;我做错了什么?
  • python怎么发图文_python3开发微信企业号发送图文方法
  • java zip文件夹_【转】Java实现将文件或者文件夹压缩成zip
  • java线程接口_Java多线程相关的常用接口
  • java 字符串 宽度,用Java计算字符串的显示宽度
  • java string转gbk_Java String UTF-8 和 GBK 互换
  • java获取jsp session_前台jsp页面获取session对象
  • java执行多条linux命令_Java ProcessBuilder可以在Linux中顺序执行多个命令
  • java怎么做好看的边框_在java中怎么做出这种文本框效果
  • java验证call_Java 判断字符串是否是回文字符串
  • java callable 泛型_java入门避坑必读,基于Callable接口实现java多线程
  • linux如何安装java环境_Linux下Java环境的安装与配置
  • mysql索引 聚集索引_JAVA面试被问mysql聚集索引和非聚集索引的区别?
  • CODING 缺陷管理功能正式开始公测
  • Fastjson的基本使用方法大全
  • Golang-长连接-状态推送
  • Javascript Math对象和Date对象常用方法详解
  • Kibana配置logstash,报表一体化
  • leetcode386. Lexicographical Numbers
  • MYSQL 的 IF 函数
  • ng6--错误信息小结(持续更新)
  • SSH 免密登录
  • Terraform入门 - 3. 变更基础设施
  • 从零开始学习部署
  • 大主子表关联的性能优化方法
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 基于 Babel 的 npm 包最小化设置
  • 将回调地狱按在地上摩擦的Promise
  • 前嗅ForeSpider中数据浏览界面介绍
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 强力优化Rancher k8s中国区的使用体验
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • (1)STL算法之遍历容器
  • (23)Linux的软硬连接
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (离散数学)逻辑连接词
  • (三)c52学习之旅-点亮LED灯
  • (一)UDP基本编程步骤
  • (已解决)什么是vue导航守卫
  • (转)EXC_BREAKPOINT僵尸错误
  • ****Linux下Mysql的安装和配置
  • ***通过什么方式***网吧
  • .Family_物联网
  • .net core 连接数据库,通过数据库生成Modell
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃