缘起
聊天内容整理文字如下
问题
现有如下表:
作业记录表T1
作业ID | 作业日期 | 机时 | 记录时间 |
---|---|---|---|
Job001 | 2022/01/01 | 1000 | 2022/01/02 |
Job002 | 2022/01/01 | 2000 | 2022/01/02 |
作业扣费表T2
作业ID | 作业日期 | 机时 | 扣费 | 扣费时间 |
---|---|---|---|---|
Job001 | 2022/01/01 | 1000 | 100 | 2022/01/02 |
Job002 | 2022/01/01 | 2000 | 200 | 2022/01/02 |
在正常情况下,一切可以工作得很好,但是事实并非理想,作业调度器也会出故障,导致作业机时发生变化。
例如在 2022/01/03 重新采集作业时 Job001 的机时从 1000
又变回了 500
,但系统对 Job001 已完成了 1000 机时的扣费
问题:如何设计数据库表在不修改已写入的历史记录的前提下,解决作业机时发生变化的问题?
情境说明:
- 机时变化是不可抗力因素,1000是错误的,后来500是正确的,但也可能最终200是正确的
- 最终时间其实不确定,如果非要给个期限,可以限定为一年内变动都是可能发生的
- 设计字段可以随意,但已存在的记录数据不能变化了
- 增加新表,新字段都不受任何限制
综合要求如下:
- 前提:可以增加新表,可以在原先这两个表基础上加字段,但是不能修改或者删除这两个表已有的字段
- 目标:以当前机时作为扣费依据,历史多扣或者少扣需要进行补扣或者补偿
我的解答
综上问题,我的解决思路如下:
1、对最关键的作业记录表增加内容Hash字段,内容为 md5(作业ID+作业日期+机时)
,该字段可作为主键,由于数据在入库前用于计算Hash的内容都是已知的,作为主键字段可以最大程度的利用主键索引提升检索效率。如果这个Hash数据不存在则在下次 作业调度器 同步作业记录时自动计入 T1 表,如果已存在则直接忽略
2、T2 表关联 T1 表的 DataHash字段,主要用于判断作业是否已扣费,便于后续扣费任务的执行
3、增加 「异常作业退费记录表T3」,用于对之前已扣费的作业进行退费行为记录。
4、若出现重复的情况(作业ID跟作业日期相同),将上一次作业(以记录时间排序)已扣费记录进行退费,并记入T3表
调整后的表结构记录如下:
作业记录表T1
DataHash字段内容为:md5(作业ID+作业日期+机时),如:
md5(Job001-2022/01/01-1000)
作业ID | 作业日期 | 机时 | 记录时间 | DataHash |
---|---|---|---|---|
Job001 | 2022/01/01 | 1000 | 2022/01/02 | 15dc9093ab0febf9aff2810891ef1a64 |
Job002 | 2022/01/01 | 2000 | 2022/01/02 | fa8f51fb2f36087a9b4c6deacf5f1dd2 |
Job001 | 2022/01/01 | 500 | 2022/08/30 | 4ec0fea71753f4a7585dc4cf4dd460f2 |
作业扣费表T2
作业ID | 作业日期 | 机时 | 扣费 | 扣费时间 | 作业记录DataHash |
---|---|---|---|---|---|
Job001 | 2022/01/01 | 1000 | 100 | 2022/01/02 | 15dc9093ab0febf9aff2810891ef1a64 |
Job002 | 2022/01/01 | 2000 | 200 | 2022/01/02 | fa8f51fb2f36087a9b4c6deacf5f1dd2 |
Job001 | 2022/01/01 | 500 | 50 | 2022/08/30 | 4ec0fea71753f4a7585dc4cf4dd460f2 |
异常作业退费记录表T3
作业ID | 作业日期 | 机时 | 退费 | 退费时间 | 作业记录DataHash |
---|---|---|---|---|---|
Job001 | 2022/01/01 | 1000 | 100 | 2022/08/30 | 15dc9093ab0febf9aff2810891ef1a64 |
评论 (0)