我实际上在担心如何设计完美的表来处理交易和佣金。特别是,我们真的不希望表在任何情况下都不同步。
基本上这就像ebay,商家卖给买家,我们从每笔交易中获得佣金。
应用程序已经使用Codeigniter构建,它有:
Merchants(id,name,balance)
Transactions(id,merchant_id,buyer_id,amount,transaction_id)
现在,如果需要,我们还需要创建哪些表来获取我们的收入和卖方的收入,以及处理退款的最佳DB机制是什么?我们是否应该将每笔存款的余额制作另一个表,而不是+x balance
行。
每当你处理任何财务任务时,总是尽可能多地存储有关它的信息。
有两种方法可以保持所有表的同步。
-
数据库级-使用存储过程和触发器等选项
-
应用程序级-使用事务(innoDB),并确保事务是原子的。(我建议这样做)
添加列commission
到Transactions
,跟踪您的佣金。这方面的数据既可以在商品定价时预先计算,也可以在交易过程中即时计算。
买方支付product cost + commission
,卖方获得product cost
,您获得commission
。如果您的佣金是一个变量(不是一个固定的费率,并且从一个项目到另一个项目变化),您可以在Items
表中有一个列来存储它。从现在开始,一切都不重要了。您只需要维护一个History
表,该表保存有关用户的事务列表。它看起来像
AccountHistory(id, transaction_type, transaction_id, amount)
您可以将AccountHistory
拆分为两个—一个用于接收资金,一个用于发送资金。
所以每次交易发生时都会发生以下情况
- 进入to
Transactions
表 - 买方进入
AccountHistory
- 更新买方余额
- 卖方进入
AccountHistory
- 更新卖方余额
所有这些都应该是原子的。
对于回滚,您可以添加一个列transaction_type
来区分回滚和普通事务,或者您可以维护一个单独的表。
使用过一个数据库,其中的设计将金融事务分散在许多不同的表中,我可以告诉您,将所有事务放在单个表中要好得多。您应该将事务类型添加到事务表中(以及一个查找事务类型的表)。
那么每笔交易可以有单独的佣金和卖方产品成本行。稍后撤消的事务将作为负金额输入。对于这些类型的事情,添加父事务字段也很有帮助,这样您就可以轻松地识别正在更改的事务。
构成事务一部分的所有数据条目都应该在存储过程中并且有事务,这样如果插入的一部分失败,整个事情就会立即回滚。这一点至关重要。它需要在存储过程中,这样没有人(除了系统dba)可以直接访问存储财务记录的表。
当你开始考虑处理金融交易时,你能做的最糟糕的事情就是只设计用户界面。你需要为你需要的财务报告进行设计。你需要咨询审计你财务的人,了解他们需要哪些信息,以及他们希望你有哪些内部控制措施来防止内部和外部欺诈。