存储银行账户和交易的数据库结构

3
我们正在为自己的商店添加一个类似银行的子系统。
我们已经有了客户,所以每个客户将被赋予一种账户,某些类型的交易将成为可能(加入或从中减去)。
因此,我们至少需要“账户”实体,“交易”实体,然后操作将必须重新计算总余额。
您会如何设计数据库来处理这个问题?
是否有任何标准银行系统可以使用,我可以模仿?
顺便说一下,我们使用mysql,但也会考虑一些nosql解决方案以提高性能。

将银行账户存储在“nosql解决方案”中不会为您赢得AAA评级。这是作业吗? - wildplasser
你需要处理利息吗?当你说像银行一样,它是否会受到像银行一样的监管? - Cade Roux
它是工作的,但没有兴趣。这就是为什么我说“银行式”的原因。约翰·多有一个帐户,可以从中取出10个伪美元,或者将总额交给他。 - user1241320
2个回答

3
我认为你不需要使用NoSQL来加速,因为它不太可能需要很多/任何并行性,并且我不确定你需要多少非模式化。除非您开始涉及跨数百万客户和数亿交易进行分析的复杂业务要求(例如盈利能力),即使在这种情况下,这基本上也是数据仓库风格的问题,如果已变得如此庞大,则首先不会在事务模式上运行。
在关系设计中,我倾向于避免需要平衡重新计算的任何设计,因为然后您最终将面临平衡修复程序等等。通过适当的索引和足够简单的设计,您可以对交易(正和负的)进行简单的SUM操作以获得余额。通过对交易的良好一致的符号约定(不会有是否添加或减去的歧义-始终添加值)和适当的约束条件(通过有限数量的交易类型,您可以指定所有存款为正数,所有提取为负数),您可以让数据库确保没有负存款等异常情况。
即使您想以某种方式缓存余额,您仍然可以依赖这种简单机制,增加一个触发器以更新帐户汇总表。
我不是一个将所有这些放在数据库之外中间层的忠实拥护者。您的基本会计应该相当简单,可以在数据库引擎中进行处理,以便执行查询的任何人或应用程序的任何部分都将得到相同的答案,而不需要涉及客户端代码逻辑。因此,使用约束条件、触发器和存储过程的组合(按照所需的增加复杂性的顺序),数据库在略高于引用完整性的层面上确保完整性。我不是在谈论您的所有业务逻辑,只是禁止由于错误的客户端编程或无法按正确的顺序执行事情或使用正确的参数调用事情而导致数据库永远不应该进入的低级别情况。
在真正的银行业务(即COBOL应用程序)中,通常数据库模式(通常是非关系型和非规范化的-许多这些东西早于SQL)会看到许多类似于过去余额的12个月桶,它们在账户翻转时进行更新和转移。这些系统使用的某些数据库有点分层。代码非常重要,因为所有事情都在代码中完成。再次强调,这有点老派且容易出问题(例如可能很像NatWest正在经历的问题),NoSQL是重新回归这种代码至上方式的趋势。我只是倾向于认为在长时间与这些事情共事后-我不喜欢拥有缓存余额的系统,也不喜欢没有时间点责任的系统-即您忽略某个日期之后的交易,您可以确切地看到某个日期/时间的事物是什么样子的。
我确信有些人已经对银行类数据库设计有了“标准”模式,但是尽管我多年来构建了几个类似于会计系统的系统,我仍不知道它们是什么——账户和交易并不那么复杂,一旦你超越这个概念,一切都变得高度定制化。
例如,在某些情况下,您可能会按照GAAP和按时间支付的合同上的某种时间表认可合同收益。在银行业务中,您有很多与成本资金等不同利率相关的利息事项。一旦您开始将业务需求与货币收支的基础混合在一起,一切都变得独特。

1

您没有说明您的应用程序是否有中间层,介于UI和数据库之间。如果有,您可以选择在哪里标记事务并重新计算余额。如果此数据库完全由一个应用程序拥有,您可以将计算移动到中间层,并仅使用数据库进行持久化。

Spring是一个框架,具有很好的基于注释的声明事务的方式。它基于POJO,是EJB的替代品。它是依赖注入、面向方面编程和优秀库的三条腿的凳子。也许它可以帮助您构建和实现您的应用程序。

如果您确实有中间层,并且它是用面向对象语言编写的,我建议您查看Martin Fowler的“分析模式”。它已经存在很长时间了,但是关于金融系统的章节今天与第一次编写时一样好。


有一个(Java)中间层。数据库将仅用于持久化。我真的很感兴趣能够避免重复造轮子的排序模式/标准。我会研究你建议的书。谢谢。 - user1241320

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接