想问问大家是怎么设计支付记录数据表的?

2017-06-06 10:54:21 +08:00
 abcbuzhiming
一般来讲,现在一家网站往往会支持好几家的支付,少点的 4-5 家,多点的七八家有可能。那么,因为每家支付通知的数据结构不一样,所以从理论上,应该一家支付就拥有专门的一张表用于记录支付他家的数据;然后为了统计方便,你还需要额外一张表记录网站上所有用户的支付行为,在这张支付行为表里,只会以用户 id 为索引记录用户进行了其中一家的支付,并记录这条支付记录 id (指向具体支付表记录里的记录)。

这种设计的冗余数据很少,但是缺点就是,你按用户 id 查支付记录时候如果要查到详细信息(比如这条支付到底支付了多少钱,买了什么东西),就必须再次进行查询,不能用简单的联表查询来解决这个问题,因为你支付方式有多家,你光联表一次不能查到全部记录。

这个问题大家有没有什么好点的办法
7563 次点击
所在节点    MySQL
14 条回复
doing
2017-06-06 11:20:58 +08:00
我觉得啊,对你的系统来说,支付重点考虑调用 api 是否成功,进行业务逻辑处理吧,应该不需要考虑”一家支付就拥有专门的一张表用于记录支付他家的数据“,就算有,也应该是自己抽取关键相关字段数据设计表保存。这张表也不应该涉及到”比如这条支付 xxx 买了什么东西“
abcbuzhiming
2017-06-06 11:45:56 +08:00
@doing 一家支付拥有专门一张表记录他家的信息有两个目的,其中一个就是你说的 api 调用是否成功,因为支付的模式基本都是支付商向你的服务器推送支付成功 /失败信息,你不记录这条信息,你咋知道这条支付是否已经处理过呢(支付商有时候会多次推送)。另外一个就是用于明细查询和对账,特别是对账时要求记录该支付推送过来的信息的全部,越详细越好,这就是为啥每家支付都专门给一张表的原因。

最后你说的问题就是我遇到的问题,不记录这条支付买了什么东西,那么查的时候你就得联表了
owenliang
2017-06-06 12:17:13 +08:00
我的做法是订单存两份,以用户维度为主表(按 uid 取模),数据实时同步到商家维度的辅表(按 poi 取模)。
doing
2017-06-06 12:34:28 +08:00
@abcbuzhiming 按你这样的业务,是需要一种支付一张表啊。第二,联表是肯定,你不可能把买了什么东西也放入到这个单独的支付表里面,买什么东西应该是你系统本身的业务数据(属于账单的关联数据,支付应该和账单有直接关系,和账单的关联数据无直接关系)。
shinwood
2017-06-06 12:39:11 +08:00
一张支付记录表
一张支付方式索引表
一张账单索引表
一张账单明细表
abcbuzhiming
2017-06-06 13:45:41 +08:00
@owenliang 没理解你的意思,用户维度的主表好理解,我也有这张表,取摸是什么意思呢,商家维度的辅助表不止一张的
abcbuzhiming
2017-06-06 13:48:32 +08:00
@doing 我这种模式面对的问题是,光联表解决不了问题,比如我按用户维度查询出了 30 条记录,这 30 条记录里,有用微信支付,有支付宝,还有银联的,你怎么联表查出具体的支付信息呢,left join 只能在纵向上连接一张表,而我需要在纵向上连接好几张表
abcbuzhiming
2017-06-06 13:49:49 +08:00
@shinwood 你把多个支付方式的详情记录在一张表里,那这张表不同类型支付信息之间冗余数据很多啊
sunchen
2017-06-06 13:57:13 +08:00
辅表的建立 我觉得一种方式是建立一个超宽的表,把各个数据源的字段全填进去,这个样所有支付渠道结果都在一个表里。另一种方案就是用 json 存储非结构话数据,如果你用的 postgres,强烈建议使用方案二
3dwelcome
2017-06-06 14:00:00 +08:00
这就是个权衡的问题,个人选择冗余数据多。相对而言,设计还是简单点,便于维护,当程序员久了,你就会觉得写复杂代码是件很容易的事,但要把一大坨代码维护好,就相当困难。

ps: wiki 上有个叫 graph database 的东西,就是用来处理 SQL 无法表述完善的网状关系结构,查询一个主节点,自动带出相关节点,和你这个需求有点接近,后端是 no-sql 的。
Fishdrowned
2017-06-06 14:09:59 +08:00
主表 orders,放订单号,金额,用户 id,支付方式,状态,创建时间,支付网关订单号,成功时间,取消时间,关闭时间,等等,通用,而且真正重要的字段。
附表 order_data,订单号加一个 json 字段,放各种乱七八糟又不统一信息,同时把订单状态更新记录也塞进这里。
然后再开两个表,放 api 发出,以及接受请求的流水记录。

以上四个表应该足够你倒腾了,不要一种支付方式开一个表。

再说你收到回调要判断怎么处理,那是主表的事(看订单状态),而不是接受记录的事。
doing
2017-06-06 14:12:04 +08:00
@abcbuzhiming 有用微信支付,有支付宝,还有银联的。。。这个不可以变成一个“虚拟的大表”吗,毕竟一个账单支付成功,手段是唯一的。
leeg810312
2017-06-06 20:36:50 +08:00
若每种支付一张表,按用户查询所有支付数据就必须关联所有支付表,实质效果就是一张大表,还不如全部支付明细存在一张表,还减少了关联呢,而且要是增加支付方式,要关联更多的表,相关 sql 也都要改,维护也很麻烦。
0915240
2017-06-06 23:19:33 +08:00
一张表存储、重要基本信息各家提取出来各存字段,其他‘冗余’的详细信息,另存 json 字段。

上 pg 或者 5.7 的 mysql .

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

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

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

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

© 2021 V2EX