【发布时间】:2014-06-14 08:06:15
【问题描述】:
我无法弄清楚如何在 PHP 中存储、检索和计算运行余额。它与 PHP 无关——它更多的是编程理论,但无论如何:
想象一下下表:
id | user_id | date | start_time | end_time | total | balance | notes
19 | 17 | 2014-04-01 | 09:00:00 | 17:30:00 | 7.50 | 0 |
20 | 18 | 2014-04-02 | 09:00:00 | 18:30:00 | 8 | 0.5 |
20 | 18 | 2014-04-01 | 09:00:00 | 17:00:00 | 7 | -0.5 |
显示当月余额相对容易:
-
计算当月(2014 年 4 月)有多少小时可用。 (假设每天工作 7.5 小时,周末不工作):
22 天 * 7.5 = 165 小时
-
使用 SQL 计算一个月的总预订时间,例如:
SELECT SUM(total) FROM booking WHERE date >= '2014-04-01' AND date
//30
-
那么余额就是总工作时数减去总可用时数:
30 - 165 = -135
我需要在多个月内以有效的方式显示这些值的运行总计,因此我不只是想 SUM() 总列,因为将来可能有数千行,这肯定在-高效?
因此,我想有一个 running_totals 表,每个用户每个月都有一行,每当编辑、添加或删除记录时,它都会自动更新。但是,这将是有问题的,因为可以更新前几个月的记录,它不仅需要更新当前月份的行,还必须级联到该月的前几个月。例如,如果您要回到 3 月更新记录,我将不得不更新 3 月和 4 月的 running_balance 行。
除非你对 running_balance 中的所有记录求和,然后在 PHP 中计算出余额?随着应用程序的增长,这对我来说似乎效率低下,我宁愿一开始就做好。
其他问题
我只想计算到今天的余额,但是你可以预订未来的时间,计算余额时应该忽略这个。
我目前是怎么做的
我想希望很快,但我认为这太复杂了,而且其中已经存在错误。所以我需要快速找到一个简单、高效的解决方案。
插入新记录
-
当您第一次预订新月份的一天时,我会计算出该月的可用总小时数(例如 2014 年 4 月)
165
-
加载 running_balance 行(每个用户 1 个)并从中减去月份总数:
0 - 165 = -165
-
添加当前预订的总数(例如 7.5):
-165 + 7.5 = -157.5
显示运行余额
从 running_balance 加载行。计算当月还剩多少小时。例如,我们在 4 月 28 日,所以还有 15 个小时(2 天 * 7.5)。
-
将其添加到运行余额中:
-157.5 + 15 = -142.5
因此,您的流动余额为:-142.5
事实证明这太复杂了,有很多边缘情况,尤其是在编辑和删除时。特别是在删除特定月份的最后一个条目时。所以,我想知道是否有更简单的方法,你们聪明的人能想到吗?
谢谢。
PS:代码的来源在这里:https://github.com/WeareJH/Flexitime 在排除问题并编写文档之前,它实际上并不处于任何可供公众使用的状态,但它可能有助于了解上下文。
【问题讨论】:
-
根据我的经验,对于运行“平衡”的事物,可以说是金融/信用卡数据……您不允许修改现有数据。您只允许发行随后只是不同交易的“信用”。无论如何,如果您需要编辑,那在您的情况下很好。但是,将余额与事务本身存储在同一个表中违反了数据库规范化的原则。将其分开最终是一个更好的主意。
-
这是有道理的,这就是我正在做的事情,每个用户都有一个 running_balance 行。我只是讨厌每个新月份必须减去月份总小时数的逻辑。
-
如果您还没有测试并确认这是一个问题,您不应该担心效率。即使有几千个用户,每个用户每天 1 个条目也是非常少量的数据。
-
我猜还有效率——正如你所说,这不是一个大问题,这与我存储和计算的方式有很大关系。这似乎不是一个干净的过程,并且有很多边缘情况。所以我想听听其他人是如何解决这个问题的。