博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库性能优化之冗余字段的作用
阅读量:4164 次
发布时间:2019-05-26

本文共 1277 字,大约阅读时间需要 4 分钟。

在设计时,某一字段属于一个表,但它又同时出现在另一个或多个表,且完全等同于它在其本来所属表的意义表示,那么这个字段就是一个冗余字段。

——以上是我自己给出的定义

冗余字段的存在到底是好还是坏呢?这是一个不好说的问题。可能在有人看来,这是一个很蹩脚的数据库设计。因为在数据库设计领域,有一个被大家奉为圭臬的数据库设计范式,这个范式理论上要求数据库设计逻辑清晰、关系明确,比如,”用户昵称”字段”nickname”本来属于表”user”,那么,表示”用户昵称”的字段就唯一的只应该属于”user”表的”nickname”字段,这样,当用户要修改昵称的时候,程序就只需要修改 user.nickname这个字段就行了,瞧,很方便。不过问题也随之而来,我在其他数据表(如订单orders表)里只存储了用户的ID,我要通过这个ID值得到用户昵称该怎么办呢?一个普遍的解决方法是通过联接(join),在查询时,通过id这个唯一条件联接两个表,从而取到用户的昵称。

这样确实是没问题,我也一直觉得这样是最好的方案,扩展方便,当要更新用户信息时,程序中要修改的地方很少,但是随着数据库里数据不断增加,百万,千万,同时,用户表的数据肯定也在不断的增加的,它可能是十万,百万。这个时候,你会发现两个表通过联接来取数据就显得相当费力了,可能你只需要取一个nickname这个用户昵称属性,你就不得不去联一下那个已经几十万的用户表进行检索,其速度可想而知了。

这个时候,你可以尝试把nickname这个字段加到orders这个订单表中,这样做的好事是,当你要通过订单表呈现一个订单列表时,涉及用户的部分可能就不需要再进行联接查询了。当然,有利就有弊,这样做的弊端就是,当你尝试更新用户信息时,你必须记得用户信息表里当前被更新的字段中,有哪些是冗余字段,分别属于哪些表,找到他们,然后加入到你的更新程序段中来。这个是程序中的开销,开销在开发人员的时间上了。至于这样做是否值得,就得看具体情况而定了。

所以,目前要创建一个关系型数据库设计,我们有两种选择:

  1. 尽量遵循范式理论的规约,尽可能少的冗余字段,让数据库设计看起来精致、优雅、让人心醉。
  2. 合理的加入冗余字段这个润滑剂,减少join,让数据库执行性能更高更快。

选择哪一种呢?如果你是一个美学狂人,并且财大气粗,非要使用第一种方案,也没关系,这种方案的短板并非不可救药的。比如,你可以增加服务器,从数据库集群入手,进行读写分离,读的时候可以将压力分散到不同的数据库服务器上,这样也可以获得很好的性能,只是多付出了硬件成本和维护成本。或者,你可以在数据库前端架设Memcached之类的缓存服务,减少读写数据库的次数,也可以达到同样的效果。问题在于你确定你需要缓存之类的东西。

当然,如果你跟我一样,只有一台每月几十元买来的vps,甚至可能是一个虚拟主机,建议还是暂时压制你的美学欲望,跟我一起选择第二种方案吧,除非你愿意你的整个数据库都一直只有零零星星的几条数据

偶有所感,欢迎拍砖,记于2011.2.28凌晨。

经典论坛交流

转载地址:http://mrvxi.baihongyu.com/

你可能感兴趣的文章
fstream默认不支持中文路径和输出整数带逗号的解决办法
查看>>
各种程序打包软件的安装命令
查看>>
Wise Installation使用中注意的问题
查看>>
WinCE开发环境的搭建
查看>>
让fstream支持中文路径
查看>>
Wise Installation使用中注意问题 总结
查看>>
wince 禁止程序标题栏上的退出按钮X
查看>>
WINCE 禁止MFC程序窗口上的OK按钮
查看>>
线程池原理及创建(C++实现)
查看>>
什么代码才是线程安全的
查看>>
基于WinCE 5.0环境项目开发心得总结
查看>>
WCDMA,CDMA2000,TD-SCDMA 网络那个更好?
查看>>
ActiveX开发详解
查看>>
带技术团队之大忌
查看>>
C++开源库【总结】
查看>>
串口通信编程--多线程异步方式
查看>>
WinCE和Windows Mobile下使用TinyXML进行C++的开发
查看>>
DLL接口的导出
查看>>
C++负数的二进制表示的计算
查看>>
一款免费的FTP客户端、服务端工具FileZilla Server
查看>>