【问题标题】:Linking together multiple database table entries from multiple months将来自多个月的多个数据库表条目链接在一起
【发布时间】:2012-08-28 17:05:23
【问题描述】:

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

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

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

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

如果 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 这是一个外键

我一直认为每个类别每个月都需要一个新条目,但从下面的 cmets 和答案看来,我最好只输入一个类别条目而不考虑月份,然后只计算飞吗?

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

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

【问题讨论】:

  • 如果您能发布一些示例(代码、表格布局等)将会很有帮助。很难想象你在这里要做什么。
  • 添加了一个db示例,希望对您有所帮助
  • 纯粹作为最佳实践:我不会创建“category_name”列,将其删除并创建一个直通表和外键。 table1, table2 创建第三个表来链接它们,table1_table2,在这个表上创建一个 id,table1_id,table2_id。在链接到其他表的那些上设置 2 个外键。
  • 好的,我明白你的意思,但不明白为什么这是一件好事?它是否将名称与其他类别信息分离,从而允许更改名称,还是我错过了好处?
  • @wes 我刚刚实现了这个,现在完全明白它为什么有用了,它解决了我最初的问题!我的数据库设计的另一个问题,那是另一个问题

标签: php mysql database web-applications


【解决方案1】:

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

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';

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

【讨论】:

  • 哇,好的。这有点让我大吃一惊,但我有点明白你从哪里来,使用数据库查询来替换我目前拥有的一些结构......我需要重新考虑我的一些基本逻辑,因为我目前只有提款交易,没有存款。有关更多信息,请参阅上面的更新 2
猜你喜欢
  • 2012-11-22
  • 1970-01-01
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多