微信公众号开发 国外镜像 PyCharm pandas 个人收款码 VBA csv matlab向上取整 vue动态绑定class vue遍历 网络营销视频 java常用的包 solidworks图库 matlab取绝对值 mysql函数返回结果集 python平方函数 python在线教程 python包 python导入文件 javaapplet java查看版本 javaworld linux内核编程 幽城幻剑录五内 内存整理工具 键盘模拟器 海妖花粉哪里多 迅雷去广告版 免费微信答题制作 脚本网站 ftp客户端软件 allowtransparency 屏幕录像机 砸金蛋抽奖活动 轮播图代码 加字幕软件 三菱plc序列号 layout软件 笔底春风 ps测量工具
当前位置: 首页 > 学习教程  > 编程语言

你有没有想过为什么交易和退款要拆开不同的表?

2020/9/19 15:14:58 文章标签:

前言


近期做新项目,在设计表结构的时候,突然想起来之前面试的时候遇到的一个问题,那时候也是初出茅庐,对很多东西一知半解(当然现在也是),当时那个小哥哥问我为什么交易和退款要拆成两个表?是基于什么考虑?有什么好处和优点么?


公众号:liuzhihangs,记录工作学习中的技术、开发及源码笔记;时不时分享一些生活中的见闻感悟。欢迎大佬来指导!

背景

那是一个风和日丽的下午,当然,风和日丽的下午应该配点其他的形容词,实在是我才疏学浅,只能用这个词充当了下开头…… (此处省略小五千字)

赶紧进入正文!

因为之前一直做聚合支付,而在使用过程中,也是支付和退款表拆开的,一直这么用,并没有觉得不妥。

比如一个交易表基本就是这样的:

字段类型含义
idbigint主键 id
trans_idvarchar交易订单号
trans_amountbigint订单金额
trans_statustinyint交易状态
………………
create_timedatetime创建时间
update_timedatetime更新时间

退款表也差不多就是这样:

字段类型含义
idbigint主键 id
refund_idvarchar退款订单号
origin_trans_idvarchar原始交易订单号
refund_statustinyint退款状态
refund_amountbigint退款金额
………………
create_timedatetime创建时间
update_timedatetime更新时间

大概两个表就是这样子的吧!像一些其他字段就先省略了,平常用着也觉得没什么。

但是恰好那次那个小哥哥就问了这个问题,支付和退款为什么要分开记录?

当时也是确实是实力不允许,我只是说了就是这么用的,把正向流程和逆向流程拆开,分开实现逻辑,比较方便。

个人见解

这里说的不仅仅是交易和退款,同时泛指正向交易和逆向交易,比如充值和消费,借款和贷款,账户出账入账等等,下面仅说说个人见解,只做讨论,如果小伙伴有更好的说法,希望可以留言指出,共同学习。

对账需要

对账户而言,出款表和入款表最后两方的金额是能对的上的,也就是说收支平衡

当然这个记在一个表里也是完全可以的。毕竟对出入账只是流水没有状态变化,比如出账中,入账中,等等,流水表完全可以记在一个里面,然后用字段进行标识是出账还是入账。

拆表需要

在网上看资料经常会说分库分表,而像订单这种(交易/退款)完全两种业务,使用两张表相对而言比较合适,毕竟交易的订单相比退款订单要多的多。

字段设计

交易和退款是完全不同的两种业务,不像账户流水就是资金记录。

交易除了订单状态还有一些交易信息比如商户号、优惠金额、实付金额、交易渠道、商品 id 名称、备注等各种信息。

退款则是根据原单进行退款,需要记录原始订单号、退款金额(部分退款)、退款信息等。

虽然交易和退款总体上都包含 订单号、状态、金额等,但是如果强行放在一个表,就会导致以下问题:

  1. 很多字段为空的情况,比如交易不需要原始订单号,退款需要存储原始订单号。本来可以设置索引来提高查询效率的字段也不太合适设置了。
  2. 状态也不一定可以完全兼容,像交易状态和退款状态就很难互相兼容。

开发效率

交易和退款分开之后,两个人负责不同的业务进行开发,包括业务逻辑和查询展示。如果放在一起,就很多字段不能保证别人知道有还是没有,是存储还是不存储,毕竟表里设置的都可以为空。这种情况下需要很多沟通,或者干脆一个人进行开发。

设计模式及原则

其他从设计模式及原则的角度上来说,可以说是职责单一,当然再高大上偏理论的我这就扯不出来了。

总结

Q&A

Q: 那前端要将两种甚至多种在一个列表展示该如何处理?

A: 在很多 APP 中大家看到的多种订单都是在一个列表里面展示出来的,比如:支付宝的账单页面。

当然,如果前端分 tab 页,分开展示不同的业务,那对后端来说简直不要太友好。不过实际往往不是这样,这时候就需要将订单统一存储。

LDZJYc-IFUqcP

在订单成功的时候存储到一个公共存储中,可以通过 MQ 等,将数据保送到另一张表/库,或者 ES 中用来存储。这样订单查询还可以和业务逻辑的表/库分开。也可以通过 binlog 进行处理,这里的方案只做参考。

结束语

之所以写这篇文章,也是为了总结一下最近工作中遇到的问题,以及处理方法。同时一瞬间想起来了很久前遇到的相同的问题。

如果小伙伴们还有别的看法,欢迎留言,发表自己的意见及看法,共同讨论。


作者:刘志航,一个宅宅的北漂程序员。

" 学,而知不足;教,然后知困。"


本文链接: http://www.dtmao.cc/news_show_200238.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?