后台系统可扩展性学习笔记(十一)Database Denormalization

之前的两篇笔记中谈到了从单库扩展到多库以承载更多的请求量以及单库(表)拆分成多库(表),打破单库的性能瓶颈。
这都是为了应对大数据量下的措施。
然而,除却数据量外,还有一个极其影响单库性能的因素——数据的组织方式。
对于关系型数据库,我们可以尝试在一定程度上改变数据的组织方式,即反范式化(Denormalization)

关于范式

可以参考以前做的笔记:
《MySQL——数据表设计三大范式》
设计范式相当于数据层的设计模式,对数据表进行解耦,使单表信息更加内聚,彼此边界分明,依赖关系更加清晰.
试想,如果相同的信息在多行中重复出现,不相干的信息也凑在同一张表中,就很容易出现一些异常情况:

  • 更新异常:只更新单行,就会出现逻辑上的不一致
  • 插入异常:无法只插入部分信息,除非让其它列先留空
  • 删除异常:删除部分信息的同时,可能会波及其它无关信息

范式化的弊端

在这些设计范式的约束下,相关联的信息被存储到了不同的逻辑表中,以致于经常需要多表联查(join操作),关系越复杂,连表查询越慢。例如分成客户表和订单表和商户表,当我们要执行的操作与这张表的部分信息都有关时,就需要进行多表join。
那么,有办法能改善查询性能吗?

  • 允许 DBMS 存储额外的冗余信息,例如索引视图(indexed views)、物化视图(materialized views),但仍遵从设计范式
  • 增加冗余数据,减少join操作,打破设计范式(即反范式化)

反范式化

所谓反范式化,是一种针对遵从设计范式的数据库(关系模式)的性能优化策略。
反范式化不等于非范式化(Unnormalized form),反范式化一定发生在满足范式设计的基础之上。前者相当于先遵守所有规则,再进行局部调整,故意打破一些规则,而后者全然不顾规则。
反范式化通过增加冗余数据或对数据进行分组,牺牲一部分写入性能,换取更高的读取性能:
在设计范式的约束下,数据表中没有冗余信息(某个数据只存放在某张表的某个单元格中),为了得到某个数据可能需要一系列的跨表查询,因而读操作性能不佳,但写操作很快,因为更新数据时只需要修改一处。
反范式化就是要打破这种约束,把某些数据在不同的地方多放几份,以加快数据检索速度。
具体操作如下:

  • 存一些派生数据:类似于往 Redux Store 中塞计算属性,把需要频繁重复计算的结果存起来,例如在一对多关系中,把“多”的数量作为“一”的属性存储起来
  • 预先连接(pre-joined)生成汇总表:把需要频繁join的表提前join好
  • 采用硬编码值:把依赖表中的常量值(或者不经常变化的值)直接硬编码到当前表中,从而避免join操作
  • 把详情信息纳入主表中:对于数据量不大的详情表,可以把全部/部分详情信息塞到主表中,以避免join操作

反范式化的代价

  • 失去了数据完整性保障:打破范式,意味着之前通过范式化解决的更新、插入、删除异常问题又将重新冒出来,也就是说,冗余数据的一致性要靠 DBA 自己来保证,而不像索引视图等由 DBMS 来保证
  • 牺牲了写入速度:由于反范式化引入了冗余数据,更新时要修改多处,但大多数场景都是读密集的,写入慢一点问题不大
  • 浪费了存储空间:存储了不必要的冗余数据,自然会浪费一些存储空间,但空间换时间一般是可接受的(毕竟内存、硬盘等资源已经相对廉价了)

参考

http://www.ayqy.net/blog/database-denormalization/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java Swing 影楼管理系统之登录功能

开头打广告,Java1234.com。 首先,来个效果图。 关键代码 1,界面层 private void Jb_DengLuActionPerformed(java.awt.event.ActionEvent evt) {// TODO add your handling code here:String UserName this.Jb_UserNameTxt.getText();String …

Bdsyn百度手机助手是何物,它是怎样神不知鬼不觉地安装到你的电脑里的?

【电脑软件管理中Bdsyn手机助手的问题】Bdsyn手机助手 is developed by Baidu, Inc. and is used by 10 users of Software Informer. 并不是本人安装的(应该是自己自己主动安装的),卸载以后过几天又会出如今软件列表里。百度搜索却无法搜索出…

后台系统可扩展性学习笔记(十二)NoSQL

文章目录NoSQL定义NoSQL种类键值存储文档存储宽列存储图形数据库NoSQL 意味着什么ACID vs. BASESQL or NoSQLNoSQL定义 不同于关系型数据库,NoSQL 数据库(也叫非 SQL 或非关系型数据库)提供的数据存储、检索机制并不是基于表关系建模的。没有…

android2.2应用开发之IccCard(sim卡或USIM卡)

tyle"margin:20px 0px 0px; font-size:14px; line-height:26px; font-family:Arial; color:rgb(51,51,51)"> 如果要做android通讯录的联系人的机卡混排显示,由于手机卡类型的不同,导致手机卡存储容量以及可以存储信息不同,就要涉…

后台系统可扩展性学习笔记(十三)缓存

文章目录在哪儿加缓存缓存什么内容缓存原始查库结果缓存数据对象怎么查询缓存结果预留缓存模式直读模式直写模式回写式缓存绕写式缓存提前刷新模式缓存满了如何处理参考读写分离、分库分表、反范式化、采用 NoSQL……如果这些扩展手段全都上了,数据响应依旧越来越慢…

[linux]gdb调试

使用gdb可以在命令行方便地调试,并且能以命令程序的方式调试源代码。 常用命令简写print-p,step-s,next-n 进入gdb //方式一 gdb test//test 为可执行文件,使用-g编译得到 //方式二 gdb -q //不显示版权信息 file test //file命令打开文件 退出gdb quit …

后台系统可扩展性学习笔记(十四)异步机制与MQ

对于 Web 服务而言,提升可扩展性的主要途径是将耗时的同步工作改成异步处理,从而允许将这些工作“外包”给多个 Worker 去做,或者提前完成能够预知的部分。 异步机制与可扩展性之间的关系需要从(异步)并行处理的优势说…

RegisterClientScriptBlock与 RegisterStartupScript区别

Page.ClientScript.RegisterClientScriptBlock而用Page.ClientScript.RegisterStartupScript是因为:RegisterStartupScript 把script放置在ASP.NET page的底部,而RegisterClientScriptBlock把script放置在ASP.NET page的顶部,用RegisterClien…

【Web后端笔记】SQL Server与java数据类型对应

编号数据库类型JDBC类型JDBC索引描述1intjava.lang.Integer4 2varcharjava.lang.String12 3charjava.lang.String1 4ncharjava.lang.String1 5nvarcharjava.lang.String12 6textjava.lang.String-1 7ntextjava.lang.String-1 8tinyintjava.lang.Integer-6 9intjava.lang.Intege…

后台系统可扩展性学习笔记

整理了一下笔记目录,将以前学习的一些知识串联起来了,比如cdn、负载均衡、中间件,以前只是各自了解了一点,现在大概理清了后台系统设计中他们各自的作用。 后台系统可扩展性学习笔记(一)概要 后台系统可扩展…

TFS 强制删除锁定文件(数据库)

TFS:TFS2010 VS:VS2012 OS:Windows2008 DB:Sqlserver2008 R2 我们在团队开发当中,版本控制是一个不可忽略的工具。我们团队使用的是TFS2010这个版本控制器。 但在团队实际协作开发当中,团队成员难免有电脑损坏或人员离职情况&…

【转】Java:String、StringBuffer和StringBuilder的区别

1 String String:字符串常量,字符串长度不可变。Java中String是immutable(不可变)的。 String类的包含如下定义: [java]view plaincopy /** The value is used for character storage. */ private final char value[]…

Linux中exit与_exit的区别

在exit,_exit的区别 - exit()与_exit()函数的区别(Linux系统中)2012-03-20 15:19:53 分类: LINUX 注:exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出&…

光标闪烁问题的解决办法

在调用Windows API函数SetCursor设置光标时,可能会碰到闪烁的问题:移动鼠标,光标在Class Cursor(即注册窗口类时指定的Cursor)与预设Cursor之间闪烁。 在MSDN上有关SetCursor函数的备注中强调,如果Class Cursor非空,那…

视频编解码基础

文章目录前戏编解码技术流程主流视频编码标准视频传输面临的问题视频传输差错控制视频传输Qos质量保证参数人类视觉系统HVS 以及相应编码措施正餐编码层次与码流结构PB帧编码IBBP序列编码结构图像编码结构条带编码结构宏块编码结构块编码结构预测技术码率控制实例H264前戏 编解…

XShell 屏幕锁定的恢复方法(Ctrl+Q)

操作XShell过程中很多时间大家会习惯性的按CtrlS进行保存. CtrlS在XShell的作用是屏幕锁定,很多朋友会无法操作,会直接把窗口关闭。 解决方法: 快捷键 CtrlQ 即能完成解锁!转载于:https://www.cnblogs.com/liangle/p/3173475.html

adb端口被占用

程序不能执行,kill掉任务管理器里面adb服务,重新连接设备仍然有错 查到可能是adb端口被占用 查看adb用的是哪个端口:C:\Users\wanglin>adb nodaemon server 查看谁占用了这个端口:C:\Users\wanglin>netstat -ano | findstr …

实时语音通讯丢包补偿技术

文章目录基于发送端丢包补偿技术原理与媒体无关的前向差错纠正媒体相关前向差错纠正交织技术基于接受端丢包补偿技术基于插入方法基于插值方法基于重构的方法应用建议非交互式交互式拓展阅读参考丢包补偿技术可以分为两类:基于发送端补偿、基于接受端补偿 基于发送…

取得裝置可以顯示頁面的寬度

利用html中的div元素取得<div id"divGetWidth" width100%></div>Jquery:var width$(#divGetWidth).width(); //获取元素宽度 Javascript:var objdocument.getElementById(divGetWidth);var width obj.offsetWidth转载于:https://www.cnblogs.…

Xcode添加静态库以及编译选项配置常见问题

本文转载至 http://www.cnblogs.com/Quains/archive/2013/08/22/3276425.html 一,Xcode编译出现Link错误,出现"duplicate symbols for architecture i386 clang"提示.问题:链接时,项目有重名文件.解决:根据错误提示,做如下检查:1.Taraget->Build Settings->Li…