在数据库设计时,部分统计字段或者需要计算的字段,要增加一个字段单独存吗

104 天前
 Renco

类似于用户的消息数,已读数和未读数,这种能直接通过表数据状态 count 查询的。

还有是类似于库存计算的,例如有某个设备数量 10 个,其他用户可购买,有使购买数量记录,这个时候,是否还需要单独给这个设备加一个剩余数量字段在每次用户使用的时候计算存一遍。还是直接通过购买记录去计算设备的剩余数量。

这个开发过程经常能遇到,但是每一位开发同事的处理方式都不一样,有的喜欢增加字段去统计,每次做业务逻辑的时候,对这个字段进行加减或者计算。还有的是喜欢通过 sql 直接做计算处理,或者通过 sql 查询出来后,在业务层里去做计算处理。

1963 次点击
所在节点    数据库
11 条回复
yor1g
104 天前
能算就不要存. 除非性能不行计算太费时. 出 bug 修数据真的很麻烦
AoEiuV020JP
104 天前
按我理解这种属于“优化”, 空间换时间, 插入时间换查询时间, 看业务看性能瓶颈决定,反正封装好确保就算换了方案对前端也没影响就是了,
b821025551b
104 天前
具体还是要根据业务情景来选择,比如你这个例子中:
用户消息数,这个可能涉及到很频繁的写入,这种就不建议用单独字段去存数据库了,都是走缓存;
库存计算,这个要看你这个统计用在什么场景、并发性如何,假如仅仅是展示,单独字段没什么问题;但是涉及到抢购,要防止超售,就不推荐用字段去存数量;

另外,你举例的这几种常用方法中,sql 里查询再由业务层计算,在高并发场景下很可能出现问题吧?
lasuar
104 天前
这个要看情况的,如果可以通过 [简单] 的代码逻辑通过事务保证一致性,那就可以冗余字段。
1018ji
104 天前
我第一时间想到的就是物化视图
wu00
104 天前
看情况
查要考虑性能,存要考虑一致性
suuuch
104 天前
各种设计其实是一个多方取舍的过程,没有万能的设计。

这个设计我一般是在看数据重要程度的,像库存、金额,这一类的计算结果必然需要落到实体表里面,优先保证数据可回溯性,并确保数据可以被完整校验和二次核查,否则程序出 bug 的情况下,损失定位都很花时间。在这个基础上再去考虑成本和性能。

像消息已读未读这种的,优先考虑性能和成本,并不考虑其它的。
woodfizky
104 天前
数据量大、计算量大的场景,可以考虑增加一个这样的数据表字段,或者是缓存,实现方式具体看情况嘛。

但是这个数据的准确度就看影响这个实际数据的业务是不是都闭环了,都会有效更新这个字段了。

甚至有的情况,维护这个字段的值本身的性能开销还比实时查询 count 大,比如说业务过于频繁,过于频繁的更新这个字段,那这个就没必要了。
wangritian
104 天前
第一版上线前实时算,代码加个 todo 后面用户多了再缓存
IdJoel
104 天前
已读数和未读数 肯定要存一下的,因为用户消息量应该会很大,单独用户的消息也会很多,不存的压力会很大吧?


库存计算 这个一般肯定也是算的,一般库存就直接同步到 redis 里面了

主要还是看计算的数量,如果列表显示、展示的次数很多写的次数很少,那一定单独弄个字段
如果不需要列表显示,低频的数据可以每次都算


关于 “能算就不要存. 除非性能不行计算太费时. 出 bug 修数据真的很麻烦” 的理论,我只能说,你代码都有 BUG 了,你不考虑修 bug ,而是考虑牺牲性能取处理这个东西,我觉得这个思路是完全不对的
RandomJoke
103 天前
@IdJoel 性能能满足业务场景,确实就没必要存,要存大多都是因为性能满足不了场景,这里的出 bug ,他的意思应该是加入字段存储,提升了复杂度,修数据需要去动存储,而实时计算则不需要

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1082546

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX