设计应用程序的问题

时间:2013-09-21 20:25:00

标签: database-design software-design

我对设计簿记应用程序有疑问。 简而言之,该应用程序可以跟踪人员之间的费用分配。每笔费用都记录为一笔交易,该组中的每个人都欠该组中另一个人的钱/从中获得金钱。

我一直在决定在哪里保留谁欠谁以及数据库中的数量。

策略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上查看一些开源会计软件项目的源代码,但我也认为得到你们的意见可能是一个好主意。

感谢。

2 个答案:

答案 0 :(得分: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,日期,详细信息,货币等)和行(用户,金钱等)。这种结构使人们能够在有多个账户被记入贷方或借记的情况下创建交易(例如,如果公司向某个客户开具发票并且在销售中征收税款,则该客户将被扣除,并且销售和税收抵免)。

如果您拥有大量帐户,大量交易以及提交年终帐户的法律需求,那么您可以创建一个表格,其中包含每年帐户的余额;计算总数将意味着从当前年度开始,并将今年的交易总数加到先前存储的总数中。但从你的问题来看,这似乎有些过分。

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

答案 1 :(得分:2)

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

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

  

谁欠谁

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