我有一个跟踪会员卡持卡人的rails应用程序,需要报告持卡人的状态。根据业务规则,状态被定义为“信誉良好”,“拖欠”或“取消”,具体取决于持卡人最近的发票是否已经支付。
发票会提前30天发送,因此刚开具发票的客户仍然信誉良好,在付款截止日期后20天的客户拖欠付款,且会员未能支付发票金额超过到期后30天将被取消。
我正在寻找关于是否最好将持卡人的当前状态存储为客户级别的字段(以及处理可能更新发票记录而不更新相应持卡人记录而导致的潜在更新异常)的建议,或者每次请求状态时根据数据库中的数据简单地计算当前持卡人状态是否更有意义(这可能会给数据库带来很大负担并减慢应用程序速度)。
建议?还是其他我没有想过的想法?
一个重要的限制因素:虽然任何人都不可能直接修改数据库,但总有这种可能性,所以我需要设置一些安全措施来防止各种数据库记录彼此不同步。 / p>
答案 0 :(得分:2)
在数据库中存储计算数据通常是一种优化。我建议你计算每个请求的值,然后监控你的应用程序的性能。如果未存储此数据的事实成为您的问题,那么是时候在数据库中重构和存储该值。
存储计算值,特别是那些可能影响多个表的值,由于您提到的原因,通常不是一个好主意。
当/如果您重构并将值存储在数据库中时,您可能需要一个批处理作业来定期检查数据完整性的值。
答案 1 :(得分:0)
最简单的方法是每次请求状态时根据数据库中的数据计算当前持卡人状态。这样,您就不会重复数据,因此重复项不会出现任何潜在问题。
如果且仅当您的测量显示此计算导致显着减速时,您可以考虑缓存该值。
答案 2 :(得分:0)
最近我有类似的决定,我决定将状态存储在数据库中。这是因为我想减少sql查询,看起来更简单。我选择这样做是因为我经常需要获得这种状态并且计算它(至少在我的情况下)有点复杂。
可能存在的问题是它不同步,因此我向子模型添加了一些after_save
和after_destroy
,以使其保持同步。当然,如果有人以不同的方式修改数据库,那就会产生一些问题。
您可以编写简单的rake任务来检查所有状态,如果需要,还可以更正它们。你可以在cron中运行它,这样你就不用担心了。