文档型/NoSQL数据库是否适合存储资产负债表?

13
如果我要创建一个基本的个人会计系统(因为我喜欢这样 - 这是一个关于我熟悉的领域的业余项目,可以避免陷入要求细节),那么像RavenDB这样的NoSQL/文档数据库是否适合存储账户及其交易?我该如何选择哪个实体是“文档”?
我怀疑这可能是那种实际上SQL数据库才是正确选择而尝试使用NoSQL是错误的情况之一,但是当我想到我对CQRS和事件溯源的了解很少时,我想知道实体/文档实际上是“账户”,而交易是针对它存储的“事件”,并且当发生这些“事件”时,我的应用程序是否还会写入到一个易于查询的读取存储中,例如SQL数据库。
非常感谢。

我猜数据库最初是为了处理财务事务而创建的,这就是它们首先成为关系型的原因。 - Alireza Savand
4个回答

8

我个人认为这是一个好主意,但我有一点偏见,因为我的全职工作是构建基于CQRS、事件源和文档数据库的会计系统。

原因如下:

事件源和会计基于相同的原理。你不删除任何东西,只修改。如果添加了一个错误的交易,你不会删除它,而是创建一个抵消交易。事件也是一样,你不会删除它们,而是创建一个取消第一个事件的事件。这意味着你要发布很多TransactionAddedEvent。

接下来,如果你在进行复式记账,记录交易的方式与你在屏幕上查看它的方式是不同的(特别是在资产负债表中)。因此,我对cqrs又很喜欢。我们可以使用正确的会计原则存储数据,但我们的读取模型可以优化,以显示你想要查看的数据。

在资产负债表中,你希望查看给定账户的所有条目。你不想看到交易,因为交易有两个方面。你只想看到影响该账户的条目。

所以,在你的文档数据库中,你会有一个entries集合。

这使得查询非常容易。如果你想看到一个账户的所有条目,你只需说SELECT * FROM Entries WHERE AccountId = 1。我知道这是SQL,但每个人都可以理解这个查询的简单性。在文档数据库中,它同样容易。而且,它将非常快。

然后,你可以创建一个平衡表,通过对accountid分组并对日期设置限制来实现。注意,根本不需要使用连接,这使得文档数据库成为一个很好的选择。


我很感激您发布这篇文章已经有很长时间了,但是我理解得对吗,Entries“表”只是用作读模型?也就是说,一个事件可能涉及多个账户(通常是2个,但有时更多),但正如您所说,当您想要查看单个账户的摘要时,唯一感兴趣的是涉及摘要账户的交易部分。 - dpwr

6

理论与架构

如果你深入挖掘会计理论和历史,就会发现“文档”应该是源头文件——采购订单、发票、支票等等。会计记录是通常可读的源文件的标准汇总。会计交易是两个或多个记录命中两个或多个账户,通过借方和贷方相平衡来绑定在一起的。账户余额,诸如资产负债表和损益表之类的报告都是这些交易的摘要。

把它想象成一个分层的架构——底层基础是源文件。如果源文件是电子的,那么它进入会计系统的文件存储层。这里可能会用到nosql数据库。如果源文件是纸张,则将其成像并/或将其与索引号一起存储在会计系统的文档层中。再上一层是数字记录,对这些文件进行汇总;每个文件由一个或多个未平衡的交易腿汇总而成。再往上一层是平衡交易;每个交易由两个或多个这些未平衡的交易腿组成。最上面一层是汇总这些平衡交易的财务报表。

源文件和外部应用程序

源文件是“唯一的真相”——而不是描述它们的记录。你应该总是能够从源文件中重建整个数据库。在某种程度上,数据库本身只是指向源文件的索引。然而,过多的人忽略了这一点,编写的会计软件将交易本身视为真相来源。这就需要另一个存储和工作流系统来处理源文件本身,最终导致典型的现代企业混乱。

这意味着任何写入会计系统的应用程序都只应创建源文件并将其添加到底层。但实际情况是,这一步常常被忽略,应用程序直接创建交易。这意味着源文件不再在会计系统中,而是在创建交易的应用程序中。这样会很脆弱。

事件、工作流和数字化

如果你正在使用某种事件模型,那么使用事件的正确场所是将源文件附加到事件上。事件随后触发将该文档解析为正确的会计记录。如果源文件已经是数字格式,则可以自动完成解析;如果源文件是纸张或未格式化的消息,则需要手动解析。这听起来像是工作流系统的开始,对吧?尽管如此,你仍然希望保留原始的源文件。文档数据库似乎是个好主意,尤其是如果它支持一种模式,可以将源文件与其结果解析和平衡的记录相互绑定。


5

您可以创建这样的系统。 在这种情况下,您有帐户聚合和时间段聚合。 时间段通常是一个月、一个季度或一年。 在每个时间段内,您都有该期间的交易。 这意味着加载当前状态非常快,而且您拥有完整的日志,可以向后查看。 时间段的原因是这通常是您实际考虑此类事物的边界。


请原谅我这个被关系制度化的大脑,但我确实有一个问题 - 交易与账户如何相关?我是检索包含交易的时间段的账户吗? - Neil Barnwell

4
在这种情况下,关系型数据库是最合适的选择,因为您有关系数据(例如行和列)。
既然这只是一个个人系统,你很少会遇到任何规模或性能问题。
话虽如此,对于个人成长和学习来说,使用类似RavenDB这样的文档型数据库将是一项有趣的练习。传统上,金融一直是非常正式的事情,而关系型数据库通常被认为比文档型数据库更正式和严谨。但是,正如您所说,此应用程序的领域在您的掌控之下,并且相当直接,因此复杂性和要求不会妨碍系统设计。
如果这是我自己的个人项目,并且我想了解更多新技术并查看它是否适用于特定领域,我会选择我感兴趣的任何内容,如果效果不佳,那么我就学到了一些东西。但是,您的情况可能会有所不同。 :)

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