IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

设置用于统计的冗余字段要谨慎

博客园-rethink log 2009-10-21 22:31:10 累计浏览 3,689 次
本机暂存

    在目前的项目中,因为涉及到一些较复杂的统计功能,我在某个表中添加了三个字段:

    nums1,nums2,nums3

    这三个字段分别为table1,table2,table3中相关的有效记录行数。

    添加这三个字段的原因如下:

    原因1: 在页面显示中,如果没有这三个字段,单纯靠sql来生成显示列表的话,需要关联三个表,这三个表都是记录较多的表,关联起来效率很低。

    原因2: 在网站的前台,有了这三个字段,可以减少对table1和table2,table3的select,提高效率。

    居于上面的原因,增加上面三个字段有利于提高程序运行的效率。

    但在真实的开发过程中,发现这样的设计存在很大缺点。

    具体的缺点如下:

    A 开发困难。table1,table2,table3中的数据增减,都要相应的对nums1,nums2,nums3进行加1或减1的操作。所以这些操作都需要用事务实现。

    B 健壮性不足:通过数据库的事务,可以保证nums1,nums2,nums3的正确性,但由于业务复杂,开发人员极有可能没有很好的保证事务的实现,而且开发人员对某些业务的理解错误,也可能会导致这些数据出错。

    在这种情况下,只要在某个时间点,数据发生了错误(少加了1,或者少减了1),错误就会一直存在下去,直到某种临界情况,才会发现问题(当然运气好的话,问题可能会一直隐藏下去)。一旦发现问题之后,修正过程可能是痛苦而危险的工作。

    因此,此处的DB设计中,这三个字段的添加是不必要的。现在回头看,此设计不符合以下设计原则:

    1 软件设计的核心问题是:管理复杂度。上面三个字段的添加,只考虑了页面显示的效率和减少数据库查询,但增加了程序的复杂度,得不偿失。

    2 减少数据冗余,减少数据依赖:逆范式化的DB设计,虽然可以提高程序运行效率。但要考虑:保持数据的一致性是否会很复杂;如果数据不一致的后果是否严重。

    那么如何在不增加上面三个字段的情况下,同时解决“原因1”和“原因2”的问题呢。可以采用如下方法:

    1 要避免大表关联,可以分别查询各个表的结果,然后在php里面进行“连接处理”。或者考虑引入临时表都是可以考虑的方案。

    2 在某些页面,如果确实需要减少对 table的select,需要用到nums1,nums2,nums3,可以将这个字段生成cache。视实际情况,cache可以放在file中,或放在APC/accelerate等中,或memcached等分布式cache中。这边的缓存策略视实际需求,可能也会比较复杂,但效率会比直接操作DB高。

    当然,如果你只是统计下浏览人数等类似数据,或者业务逻辑很简单的话,那还是直接添加个统计字段,并在必要的操作上时加上事务就可以了。

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. 如何查找消耗资源较大的SQL (累计阅读 15,211)
  2. 搜索引擎的特殊用法 (累计阅读 8,123)
  3. HBase性能优化方法总结 (累计阅读 7,083)
  4. 在百度的第一年 (累计阅读 6,922)
  5. SQL里是否可以使用JOIN (累计阅读 6,818)
  6. MySQL使用为什么要分库分表 (累计阅读 5,394)
  7. Fastbit中的bitmap索引算法 (累计阅读 5,289)
  8. 多维度分类排行榜应用:用位图索引 (累计阅读 5,251)
  9. 如何建立索引 (累计阅读 4,693)
  10. MySQL和MongoDB设计实例对比 (累计阅读 4,687)