mysql 对账语句_关于对账的一些理解

目录:

对账的目的

在会计中,对账的目的是为了保证账簿记录的真实、准确,主要是为了保证资金的正确可靠。

在财务、支付系统中都会引入对账系统。

一个扣款系统的示例

这里先举个例子,供下文使用。

【系统A】调用【系统B】对用户进行扣款操作。

【系统A】用 MySQL 表 table_a 记录扣款流水,字段如下:

字段

说明

user_id

用户标识

amount

扣款金额

deduct_sn

扣款单号,用一个全局唯一ID生成系统生成,要求全局唯一,会传到系统B。

status

状态。1初始化,2扣款成功,3扣款失败

create_time

创建时间

update_time

更新时间

【系统B】用MySQL 表 table_b 存储扣款流水。字段设计恰巧和 table_a 一致。

对于【系统A】的构建者而言,能保证系统 95% 无逻辑问题。也就是 5%的可能性有隐式逻辑问题。

显式逻辑问题,比如【系统A】一运行就报错;

隐式逻辑问题, 比如【系统A】运行时不报错。但是预期是对用户1扣款,结果调用【系统B】时,变成对用户2扣款,扣款正常,但是扣错人了。

【系统A】如何提升业务正确性?

为什么要对账?

引入【对账系统】后,【对账系统】对【系统A】和【系统B】的数据进行核对。对于【对账系统】的构建者而言,能保证该系统 95% 无隐式逻辑问题,就是存在 5% 的可能性有逻辑问题。

我们计算下各种概率:

系统A是否有隐式逻辑问题

对账系统是否有隐式逻辑问题

概率

情况1

5%✖️5% = 0.25% 。

情况2

95%✖️95% = 90.25% 。

情况3

5%✖️95% = 4.75%

情况4

95%✖️5% = 4.75%

情况1、2 中,我们看到的是系统稳定运行,但不知道有没有问题。

情况3、4 中,对账系统会报错,我们要检查是【系统A】出了问题,还是【对账系统】出了问题。通过问题定位和修正,我们将每个系统出现隐式逻辑问题的概率从 5% 降到更低,例如降低到了 3% 。

对账能发现什么问题

对于扣款系统能发现下面的异常。

系统间异常

【系统A】有扣款成功流水,【系统B】没有对应的扣款成功流水。

【系统B】有扣款成功流水,【系统A】没有对应的扣款成功流水。

系统内异常

deduct_sn 出现重复。

对账的使用场景

对账的本质是通过引入一个【旁观者】,提升当前流程、业务的正确性。

既然是为了【提升当前流程、业务的正确性】,那么财务、支付外的系统,也应该尽可能的引入对账系统。但此时处理的数据与钱无关,也就不是【账】。此时,可以称之为核对、数据核对,或者说广义的对账。

在财务系统中,引入对账系统,会尽可能保证钱没有问题。

在券系统中,引入对账系统,会尽可能保证券没有多发,或者没有少发,或者没有一券扣多次,或者没有券未扣钱。

甚至,在个人发布文章时,通过引入一个旁观者帮忙review,可以尽可能的保证文章的一些数据、引用等内容的正确性。

对账的实时性

对账在大部分场景中是事后行为。

根据实时性可分为:

准实时对账。比如业务发生后,5分钟内完成对账。

离线对账。比如每天进行一次全量对账。

如何对账

还是以【系统A】调用【系统B】对用户进行扣款操作为例,两个系统都有【扣款流水】。扣款单号是全局唯一的,两个系统都会记录。

离线对账

假设是每日核对,

将两个系统的 DB(最好是从库)数据导入 HIVE 中,每天导入一次,写一个 FULL JOIN 类型的 HQL (类似SQL)核对今天零点之前的数据。比对两边相同单号的成功状态的记录,关键信息是否一致。比如用户ID、金额。

另外,要考虑跨天问题。比如【系统A】中的某条扣款记录创建时间是 23:59:59,【系统B】是第二天的 00:00:01 创建。这种情况数据可能对不上,但可以先忽略。

假如今天日期是 2020-01-30

全量对账代码示例:

增量对账代码示例:

准实时对账

【分钟级】的对账可以称作【准实时对账】。

对账的本质思路是一样的。不一样的是,每次对的是最近几分钟的发生业务。

实现上,可以写一个定时任务,没3分钟跑一次最近6分钟的业务数据对账。

数据源最好是DB从库。

系统内数据核对

如果【系统A】中,扣款记录基于用户ID分库分表。因为要求扣款单号 deduct_sn 全局唯一,所以单表中最好对 deduct_sn 加上唯一索引。但是这只保证了单表中全局唯一,无法保证所有的表放在一起后全局唯一。

此时,关于唯一性问题,我们两个选择:

选择1:完全相信扣款单号生成系统。

选择2:不完全相信扣款单号生成系统。

对于选择2,我们可以加一个数据的离线核对,核对SQL如下:

如何处理对账异常数据

总的原则是,先将异常数据记录下来,找到原因并处理好后,将结论和处理流程记录下来。

事前、事中、事后

系统可以通过事前、事中、事后3个阶段来增强系统正确性,其中对账属于【事后】。

以【扣款系统】为例:

事前:代码 review

单元测试

测试环境测试

线上灰度验证

事中:数据库唯一索引约束

【系统B】收到扣款请求后,将金额和用户ID与反查【系统A】该扣款单对应的金额和用户ID比对。不一致,则拒绝扣款。

事后:对账。

留一个问题,在分库分表的场景下,deduct_sn 如何在【事中】保证全局唯一?

(待完善)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值