我正在开发一个个人理财追踪器(为了好玩!),我有一个类别表。每个类别都是表格中的一个条目,在月末它们全部重复,相关余额重置为新月份的月初读数。
其中,这些类别可以是“储蓄”类型,因此有一个总计。如果我想要检索一个类别或更新它,那么我使用了category_id字段,这适用于当前工作月份,但将几个月连接在一起正在打破我的大脑。对于储蓄类别,我想展示running_total在过去六个月中的增长情况,但在我目前的数据库设计中,类别不会“知道”他们之前几个月,因为它们是在每个月初创建的。
我目前唯一可以检索保存running_total的最后6个月的方法是按类别名称搜索,但这可能不可靠。
我考虑在表中添加一个字段“previous_month_category_id”,它可以作为将类别链接在一起的方法,但实现起来很昂贵,因为每次从中抓取“previous_month_category_id”需要6次MSQL操作结果,然后重新运行查询。
如果MYSQL可以进行某种递归,那么这可能会起作用,但我觉得有一个更明显的答案盯着我看。
我正在使用Codeigniter和MYSQL,但如果需要,不要害怕vanilla PHP。
如何做到这一点的帮助会很棒。
更新1:
以下是储蓄类别可能与其他类别混合的样本。在每个月末,使用相同的category_name,type,buget,year和users_id复制条目,但category_id自动递增,月份更新为新月份数,运行总计是先前的running_total +预算。如何在不使用category_name的情况下执行一个数据库查询来检索它们?由于这可能会改变,用户决定在7月底将其称为“Bigger TV”
+-------------+--------------+------+--------+---------------+------+-------+----------+
| 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以外的任何方式将它们全部链接。
我试图实现一些数据库规范化,但这是我实现的第一个已经了解规范化的模式,所以我可能错过了它的某些方面,并且可能避免任何过度归一化的地方感觉不对
以下是我的表格:
类别
+-------------+--------------+------+--------+---------------+------+-------+----------+
| category_id |category_name | type | budget | running_total | year | month | users_id |
+-------------+--------------+------+--------+---------------+------+-------+----------+
交易
+----------------+--------------+--------+------+----------+------------------------+
| transaction_id | description | amount | date | users_id | categories_category_id |
+----------------+--------------+--------+------+----------+------+-------+---------+
它们加入了category_category_id,这是一个外键
我总是假设每个类别每个月都需要一个新的条目,但从下面的评论和答案看来,我最好只用一个类别条目,不管月份,然后只计算一切飞?
虽然,预算可以由用户更改,因此为了记录保存,我不确定这是否也会起作用“存款”从未真正发生过,只是在月底重复的类别所以我猜测需要处理.....
此应用程序的目标一直是将财务跟踪与银行帐户中发生的实际交易分离,并为某些人提供财务层面,从而允许用户避免难以解释交易等,只关注所有现金位置。在这个系统或银行账户中没有“收入”的概念。
答案 0 :(得分: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';
还有很多其他的可能性,但这里的目的只是为了展示一种更好的存储数据的方法。