`
hq185fvl
  • 浏览: 5780 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

数据表结构设计和缓存优化的经验教训

阅读更多
    最近给XX客户实施的物资系统已经顺利度过了试用期,进入稳定运行期了,各项功能基本已经不再变更,稍微清闲了一点,因此想在性能上更完善一下,我想对系统的各数据查询进行缓存处理,降低数据库的IO次数,提高数据的查询效率,仔细阅读了一下Ehcache的应用场景和注意事项,突然发现能缓存的数据很有限,基本不能起到优化的作用。现将我们项目的情况和系统数据结构设计概况做一个大致的介绍,并针对此情况进行一下自我剖析,说丑点就是做一个数据设计的反面典型吧,哈哈,希望广大同行能共同交流提出更好的意见和建议。
    一、项目概况:
      物资管理应该是个传统型业务了,因为客户对他们需求和目标描述的并不清晰,因此这个系统我们采用的是原型开发模式,在设计初期很多时候考虑的是客户的需求,和开发的效率,主要的目的是能够实现快速迭代,弱化了对数据结构的设计,具体表现是我们将经常变动的物资的金额和数量都保存在同一表结构中了。
   
二、采用技术框架:传统的SSH,UI: Ext js。DB:Oracle 10g

三、具体举例
    很多表结构大致设计都类似如下(只选取了关键字段)
物资编码表:
ID 编码 名称 单位 单价 数量 金额
1 0001 柴油 吨 6000 10 60000

优点:数据操作简便,在新增记录和修改记录的时候,直接使用Hibernate对单实体进行操作,查询的时候也可以一次查出该项记录,不必做连接查询。

缺点:因为单价、数量、金额这三个字段会随着每次物资的出入库,频繁的进行更新。据Ehcache的描述,对于频繁修改的数据,需要频繁的和数据库和内存之间进行数据交换,从这点可以看出,数据的命中率肯定比较低,这样不仅不会提升效率而且还会大大的降低系统的性能。且可能造成数据的不一致,如果遇到每月系统自动扎帐,系统的调度任务调度该月物资出入库明细情况,碰巧遇到缓存数据和数据库数据不一致的情况,那该月将直接影响物资财务数据。而财务管理要求每月几百万的出入金额不能出现一分的误差,得严格遵循本月库存=上月库存+本月入库-本于出库这个铁律。而数据的不一致很可能就造成上述等式不成立,这在财务管理业务中是绝对不允许的。

我的目标:我想把日常经常查询的物资基础信息(名称,单位、型号等)、需求计划基础信息、领用申请等基础信息放到缓存中。以提升系统效率,降低数据库的压力。

解决方法:将物资编码表、物资计划表、采购计划表等表中相对固定的字段和频繁更新的字段进行拆分,达到低频率变更和高频率变更数据分别存储,这样就可以使用Ehcache,Redis,或memcached等相关缓存组件对低频率更新高频率查询的数据载入缓存,而对于高频率更新的数据采用实时查询方式。这样就降低了数据库的IO次数和数据查询量,对数据库的查询就变成了尽量查询更新频率较高的数据了。在提升效率的同时消除了重要数据的不一致性,达到了缓存优化的目的。
那么问题就来了,因为该项目目前已经进入了稳定运行期,系统的各项性能都在指标范围之内,并已顺利通过了验收。数据结构的任何变动理论上都可能带来系统的不稳定,若要达到上述的目的,并保持系统的稳定,那我们就必须对原有系统DAO层逻辑进行大量的改造和回归测试,这我们这种做企业级应用的公司来说,在客户不额外增加费用的情况下,同时消耗本公司资源的情况下,老板是不赞同的。呵呵,除非出于技术情怀,在不影响正常工作的情况下,自愿加班加点的改造,但白天上班已经很累了。加班加点的改造,我的情怀还没上升的那种为追求完美,可以为性能废寝忘食的地步。
    我上述的目标纯粹是从对系统锦上添花的角度考虑的。也是对整个项目在数据结构设计的角度进行了自我剖析,回想一下,若一开始我们在数据结构设计的时候就考虑了后来的性能调优需求,而不是一味的考虑快速迭代,只考虑编写代码方便省事。大概后来就不存在现在看到系统的不足,但又无能为力的窘境了。
特此留文,警醒自己,在以后的工作中,不能再犯类似错误。
1
4
分享到:
评论
1 楼 huangyunbin 2016-03-30  
感觉加缓存没必要改表结构吧

相关推荐

Global site tag (gtag.js) - Google Analytics