0

我正在开发一个个人理财追踪器(为了好玩!),我有一个类别表。每个类别都是表中的一个条目,并且在月底它们都被复制,其相关余额重置为新月份的月初读数。

其中,这些类别可以是“储蓄”类型,因此有一个运行总数。如果我想检索一个类别或更新它,那么我使用了 category_id 字段,这对于当前工作月份来说效果很好,但是将月份链接在一起会让我大吃一惊。对于储蓄类别,我想展示 running_total 在过去六个月中是如何增加的,但在我当前的数据库设计中,类别不“知道”它们之前的几个月,因为它们是在每个月初创建的。

我目前可以检索最近 6 个月的储蓄 running_total 的唯一方法是按类别名称搜索,但这可能不可靠。

我已经考虑向表中添加一个字段“previous_month_category_id”,它可以作为将类别链接在一起的一种方式,但实施起来会很昂贵,因为每次从结果中获取“previous_month_category_id”都需要 6 个 MSQL 操作,然后重新运行查询。

如果 MYSQL 可以进行某种递归,那么也许这可以工作,但我觉得有一个更明显的答案在盯着我看。

我正在使用 Codeigniter 和 MYSQL,但如果需要,我不会害怕原生 PHP。

关于如何做到这一点的帮助会很棒。

更新 1:

以下是储蓄类别与其他类别混合的示例。在每个月末,该条目会重复使用相同的 category_name、type、buget、year 和 users_id,但 category_id 会自动增加,月份更新为新的月份编号,并且运行总计是之前的 running_total + 预算。我将如何在不使用 category_name 的情况下进行一个数据库查询来检索这些?由于这可能会改变,用户决定在 7 月底将其称为“更大的电视”

+-------------+--------------+------+--------+---------------+------+-------+----------+
| category_id |category_name | type | budget | running_total | year | month | users_id |
+-------------+--------------+------+--------+---------------+------+-------+----------+
|      44     | Big TV       | sav  |   20   |      240      | 2012 |   8   |   77     |

+-------------+--------------+------+--------+---------------+------+-------+----------+
|      32     | Big TV       | sav  |   20   |      220      | 2012 |   7   |   77     |

+-------------+--------------+------+--------+---------------+------+-------+----------+
|      24     | Big TV       | sav  |   20   |      200      | 2012 |   6   |   77     |

更新 2:

我不确定我是否很好地解释了自己,所以我将详细介绍该应用程序的工作原理,看看是否有帮助。

我有名为“类别”、“交易”和“用户”的表格。类别可以是三种类型之一,1:现金,2:定期付款,3:储蓄。将现金和定期付款类型视为桶,在每个月初,每个桶都已满,目的是从中取出钱并确保在月底还有一点钱(或至少没有消极的)。

这可以按月计算,而且效果很好(对我来说,我认为我已经使用这个系统 2 年了)。这次旅行伴随着储蓄,因为它们逐月联系在一起,更像是一个大桶,每个月都会添加(有一个称为预算的固定增量),直到它溢出然后被耗尽(就像你购买时的大电视一样它),或者取材于这里和那里,目的是建立一个应急基金(比如“当我的车坏了”类型的东西)。

当为每个类别显示相关信息时,仅显示当前月份的现金和常规月份,因为这是最重要的,但对于储蓄而言,当前金额也会显示,但最好显示一个小的历史图表,说明如何随着时间的推移,它已经积累(或耗尽)。为此,我需要某种方法来搜索这些类别的上个月末状态,以便可以绘制图表,但目前我无法弄清楚如何通过 category_name 以外的任何其他方式将它们全部链接起来。

我试图实现一些 DB 规范化,但这是我实施的第一个了解规范化的模式,所以我可能错过了它的某些方面,并且可能避免了任何感觉不正确的过度规范化。

以下是我的表格:

类别

 +-------------+--------------+------+--------+---------------+------+-------+----------+
 | category_id |category_name | type | budget | running_total | year | month | users_id |
 +-------------+--------------+------+--------+---------------+------+-------+----------+

交易

+----------------+--------------+--------+------+----------+------------------------+
| transaction_id |  description | amount | date | users_id | categories_category_id |
+----------------+--------------+--------+------+----------+------+-------+---------+

他们加入了 categories_category_id 这是一个外键

我一直认为每个类别每个月都需要一个新条目,但从下面的评论和答案看来,无论月份如何,我最好只输入一个类别条目,然后即时计算所有内容?

虽然,预算可以由用户更改,因此为了保存记录,我不确定这是否可行,“存款”也从未真正发生过,它只是在月底重复的类别,所以我想那会需要处理......

这个应用程序的目的一直是将财务跟踪与银行账户中发生的物理交易脱钩,并为某人的财务提供一个层次,从而使用户能够避免难以解释的交易等,而只关注所有现金头寸。在这个系统中没有“收入”的概念,也没有银行账户的概念。

4

1 回答 1

2

在我看来,您的数据库设计可能需要一些工作。我仍然不完全熟悉您真正想要做什么,但我最初的想法是将每个事务作为单行存储在表中,然后以不同方式查询该表以生成不同类型的报告它。像这样的东西:

transactions:
+----+---------+--------+---------------+-----------+-------------+
| id | user_id | amount | running_total | datestamp | category_id |
+----+---------+--------+---------------+-----------+-------------+

categories:
+----+------+------+
| id | name | type |
+----+------+------+



不要根据时间增加类别。当您实际上有一个新类别时,将一个条目添加到类别表中。如果一个事务可能属于多个类别,则使用第三个(关系)表将事务(基于事务 ID)与类别(基于类别 ID)相关联。

当您有存款时,该amount字段将为正数,而对于提款,该字段将为负数。您可以通过执行以下操作来获取当前的运行总数:

SELECT running_total FROM transactions
WHERE id = (SELECT MAX(id) FROM transactions WHERE user_id = '$userID');

您可以通过执行以下操作找到特定月份的总差异:

SELECT SUM(amount) FROM transactions WHERE DATE('%c', datestamp) = '$monthNumber';

您可以通过以下方式找到特定类别的总支出:

SELECT SUM(t.amount) FROM transactions t
INNER JOIN categories c ON t.category_id = c.id WHERE c.name = 'Big TV';

还有很多其他的可能性,但这里的目的只是为了展示一种可能更好的方式来存储您的数据。

于 2012-08-28T17:47:59.103 回答