› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
abcbuzhiming
V2EX  ›  MySQL

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

  •  
  •   abcbuzhiming · Jun 6, 2017 · 8627 views
    This topic created in 3409 days ago, the information mentioned may be changed or developed.
    一般来讲,现在一家网站往往会支持好几家的支付,少点的 4-5 家,多点的七八家有可能。那么,因为每家支付通知的数据结构不一样,所以从理论上,应该一家支付就拥有专门的一张表用于记录支付他家的数据;然后为了统计方便,你还需要额外一张表记录网站上所有用户的支付行为,在这张支付行为表里,只会以用户 id 为索引记录用户进行了其中一家的支付,并记录这条支付记录 id (指向具体支付表记录里的记录)。

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

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

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

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

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

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

    上 pg 或者 5.7 的 mysql .
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2453 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 58ms · UTC 06:34 · PVG 14:34 · LAX 23:34 · JFK 02:34
    ♥ Do have faith in what you're doing.