0

我有一个关于设计簿记应用程序的问题。简而言之,该应用程序跟踪人们之间的费用分配。每笔费用都记录为交易,组中的每个人要么欠/从组中的另一个人那里得到钱。

我一直在决定将谁欠谁以及欠多少的总数保存在数据库中的位置。

策略 1:只需将最近的总数保留在数据库表中,如下所示(对于 3 个用户)

id  user_from user_to  money
1        1       2     23       //User 1 gets $23 to 2
2        1       3     -15      //User 1 owes $15 from 3
3        2       3     10       //User 2 gets $10 from 3

当新事务被添加到数据库中时,我会通过计算新的总数来更新这些表。所以我只为每个用户保留最新的可用负债。这样做的问题是,由于我没有为每笔交易保留余额(或快照),我将无法转到某个交易 x 并找出在该特定交易中谁欠/从其他人那里得到了多少。我只能获得所有交易的总余额。

策略 2:执行策略 1 加上以下 将每笔交易的交易总额/余额保存在另一个数据库表中(就像在每笔交易结束时显示余额的银行对账单一样)。我看到的问题是,如果旧交易值发生变化,我必须更新之后所有交易的余额(总计),因为旧交易的总数现在已经改变>

我尝试在 sourceforge 上浏览一些开源会计软件项目的源代码,但我也认为征求你们的意见可能是个好主意。

谢谢。

4

2 回答 2

2

如果您想要一个规范化的数据库,那么您不应该在任何地方保留总计。相反,您只需遍历事务表并对每个帐户的值求和。

为了使这更容易,最好更改事务表的结构:删除“user_to”字段,以便每个物理事务由表中的两行表示。您的结构将类似于

trans   // primary key
user    // foreign key to users table
money
curdate
details  // a varchar field which holds the details of each transaction

将您的数据转换为新结构将提供如下数据

1;1;23;20/09/2013;concert tickets
2;2;-23;20/09/2013; concert tickets
3;3;15;21/09/2013;whatever
4;1;-15,21/09/2013;whatever
5;2;10;22/09/2013;
6;3;-10;22/09/2013;

然后计算某人的余额就变成了

select users.name, sum (transactions.money)
from transactions inner join users on users.id = transactions.user
group by users.name

这种表结构要求您使用 sql 事务来确保您始终将一对匹配的行写入表中。

在真实会计程序中,交易表分为两部分:标题(包含交易 ID、日期、详细信息、货币等)和行(用户、货币等)。这种结构使人们能够创建有多个帐户要贷记或借记的交易(例如,如果公司为某事向客户开具发票并且对销售征收税款,那么客户将被借记并且销售和借记税收抵免)。

如果您有大量账户、大量交易并且法律需要提供年终账户,那么您可以创建一个表格,其中包含每个账户在每年年底的余额;计算总额意味着从今年年初开始,并将今年的交易总额添加到先前存储的总额中。但从你的问题来看,这似乎有点矫枉过正。

如果您只想显示给定日期的交易但仍显示总数,那么您需要两个查询:一个计算到给定日期的总数,另一个显示给定日期的交易。期末余额将是期初余额和所有显示交易的总和。

于 2013-09-22T05:02:27.743 回答
2

满足您要求的基本草稿模型将如下所示:
会计草稿 对于任何User(我更喜欢客户)我们将有一个或多个Accounts,帐户有一个名为的属性,该属性Balance将显示帐户的重命名余额。
在该模型中,Transaction记录是一个金融行为单位,其中涉及两个或多个交易方,任何交易方都有一个账户,通常交易方(账户)中的一个将被借记,另一个将被记入贷方。

当事务发生时(在验证和业务逻辑之后):
将在事务表中插入一条记录。
两个或更多记录将被插入到事务详细信息表中。
帐户表中的两条或多条记录将被更新(余额字段将被更新)。

谁欠谁

在您的示例中,这可以通过交易明细表的金额字段中的负号简单地存档。
在现实世界中,这将更加复杂,并且需要额外的表格和业务逻辑,例如在银行业中实施透支和备用存款。

于 2013-09-23T05:45:31.567 回答