复式记账数据库设计

Dmi*_*sev 31 database-design

我正在创建会计软件。我需要强制执行复式簿记。我有一个经典的问题,每笔交易一行而不是两行。

让我们举一个例子,看看它是如何在这两种情况下实现的。

考虑 accountCash和 account Rent。当我支付每月租金时,我会从我的Cash帐户中将 100 美元转入我的Rent帐户。

每笔交易一行

在一行系统中,此类事务将存储为:

交易

 tx_id | posting_date
 1     | 23/05/2015
Run Code Online (Sandbox Code Playgroud)

交易记录

 id | tx_id | credit_account | debit_account | amount
 1  | 1     | Cash           | Rent          | 100.00
Run Code Online (Sandbox Code Playgroud)

每个事务两行

在两行系统中,我必须镜像相同的交易记录以创建相反的记录,一旦我将两者相加,我就会得到零余额。

交易

 tx_id | posting_date
 1     | 23/05/2015
Run Code Online (Sandbox Code Playgroud)

交易记录

id  | tx_id | type   | account | amount
1   | 1     | credit | Cash    | 100.00
2   | 1     | debit  | Rent    | 100.00
Run Code Online (Sandbox Code Playgroud)

问题

首先,我要注意:我同时拥有transactionstransaction_records表(而不是一张表)的原因是能够处理拆分交易(我从Cash帐户中将100 美元转移到两个或多个不同帐户的情况)。

起初我试图用每笔交易一行来实现这一点,但是计算帐户余额并实际检索数据很痛苦。

我倾向于第二种情况;但是,它也有一些问题:

  • 如何更新单个记录?假设我犯了一个错误,我没有记录 100 美元的租金,而是记录了 10 美元。我现在有 2 个transaction_records- 一个用于贷方,一个用于借方,金额均为 10 美元。
  • 现在我做了我的对帐,我想修正这个错字。我将如何在数据库中解决这个问题?我不知道记录之间的联系,并且在拆分的情况下,一个事务可以有 2 个以上的记录。我想出的唯一解决方案是ref_id为每个记录对添加一些,以便在特定tx_id.

哪种方法更好/更简单?


为了简化我的问题:我想表示资金从账户 A 到账户 B 的移动。我给出的两个场景都是存储此类交易的有效设计。正如我还指出的,它们都有优缺点(第一个:更容易保存,更难检索;第二个相反)。

他们可能有我现在没有发现的其他优点/缺点,因此我询问更有经验的人的意见。

Pie*_*ens 19

一个杂志是一个指定类型的会计制度的所有事务的年代列表。这是一个简单的 Sales (on Account) 日志的分类账纸的经典演示:

在此处输入图片说明

请注意,每一行都是单笔交易,总借方 = 总贷方;并且每笔交易都打到相同的三个帐户。一个现金销售杂志看起来相似,但更换色谱柱应收账款借方与一个标记Cash银行。一个现金支出杂志将有标记的第一列Cash信用卡和附加列,如应付账款借方员工费用借方

数百年来,这种演示一直是标准配置,直到几十年前个人计算机变得负担得起为止。它有一个显着的优势,即通过简单地检查每一行来轻松验证每个事务是否平衡。同样,在将此类交易的页面发布分类之前,可以类似地验证页面总数。这是许多会计系统中使用的批处理模型。

很容易看出,当从字面上转录到自动化系统时,这个纸模型具有显着的缺点:

  1. 数据结构是一种旋转的数据结构,而经验表明,针对折叠数据结构进行编程要简单得多(也更健壮和更容易验证);和
  2. 因为每个专门的期刊都涉及不同的帐户集,所以每个这样的期刊都必须单独设计和编程,这是一种浪费且容易出错的活动。

由于这些原因,通常建议使用Specialized Journals设计作为会计系统的接口,但设计一个数据结构可以作为多个期刊的数字存储库。在现代 RDBMS 中,这具有潜在优势,即总账,甚至是专门的子账,都可以成为日记账上的索引视图,完全消除了对过账流程(日记账交易被锁定并拥有其帐户的步骤)进行编码的要求总数转录到各种分类帐)。

无论您最终采用何种数据设计,关键是为每种交易类型(即等效纸质系统中的每个专业期刊)拥有一个单独的过账分录,其中进行余额检查。


我的观点是,您提出的两种方法都是不健全的复式簿记机制。第一点:日志是一次写入的表,这是有充分理由的。有时,两个虚拟表Pending Entries 和 Posted Entries 并置在单个数据结构中,但IsPosted位始终是只写的,系统必须确保维护 Posted Entries 记录的只读性质。

会计师在过去 800 年中发布日记帐分录的方式已完全标准化。纸质演示文稿和健全的电子演示文稿之间的唯一区别是,折叠桌结构在后一种情况下更方便,而前者中的旋转桌结构在历史上在需要高度并行处理时最为重要 - 即每个都有很多职员维护单一或少量的专业期刊。历史上只有主计长有权使用通用日志。

请注意,在上面我指定日志条目是完全规范化的;日志条目是所有交易的时间顺序记录,按特定于每种交易类型的日志分组。该帖子日记帐分录的总帐是一个独立的努力和,而在自己的完全正常化,是帐户,所有交易汇总的日记帐分录(总帐)或详细(分类帐)的冗余副本。日记帐和分类帐都独立使用复式簿记。

@Codism 任何会计系统,DEB 或 SEB,都会为您记录的所有帐户提供通用报告。请注意,在内部,子分类账根据定义是单项簿记记录;另一边是资产负债表上相应的控制账户。DEB 确保对于每一美元资产,都有对资产的商业债权的精确记录,即资产中股权,无论是债务股权(又名负债)还是所有权股权,以及这些债权的优先级,如果组织破产。

  • 你能举一个你可能推荐的表结构的例子,并且不会受到你提到的缺陷的影响吗?我不确定我是否正确理解了您的建议! (6认同)

Seb*_*api 7

实际上,所提出的单行记帐模式允许进行适当的复式记帐(始终指定借方和贷方帐户),而不会引入“金额”数据的冗余。

单行模式为您提供了一种通过构造进行平衡的复式条目的实现,因此不可能“失去平衡”。机器可能会即时重新计算分类帐。

您必须执行 2 个选择而不是一个来检索分类帐。

请注意,除了交易拆分之外,还有其他交易(例如外汇交易)可能会以 2 条记录而不是 4 条记录结束。这完全取决于您是否会稍微反规范化一下,只需输入 4 条具有类似描述的交易即可。

您可以阻止输入或修改任何事务以维护审计跟踪,如果您希望能够审计事务日志,这是必需的。

在上面的线程中,对于 CPA 来说,“完全规范化”似乎意味着所有会计师都认可的规则,而对于程序员来说,它具有不同的含义,即没有存储派生或冗余数据。

会计数据所包含的全部内容是一组交易,这些交易给出了金额以及它们从哪个账户流向哪个账户,以及它们的日期、一些描述(和其他附件)。分类帐和余额是通过汇总从这些交易数据中得出的简单视图。


Vér*_*ace 5

我可以建议您看看这个领域的开源软件宝库吗?

谷歌的“开源复式记账软件”给出了几个有希望的调查途径。

您可以在此处查看 GNU 会计软件包、几个评论站点(12),最后是会计软件wiki,其中有一个关于自由软件的部分。

我确信通过检查一些 F/LOSS 源代码和模式,您可能会得到一些关于如何编写适合您自己特定需求的模式和/或软件的很好的提示和指示。