用于跟踪和分摊费用的数据库设计

时间:2018-11-29 13:37:19

标签: mysql database database-design

我想设计一个Web应用程序,以跟踪组织成员的财务状况。某些功能与Splittr非常相似。我使用MWE数据库图定义需求:

  • “财务”表:每个用户都有一个个人财务帐户,我正在使用以下三个 red 表: enter image description here
  • “ SharedExpense”表:每个用户可以与许多“共享费用组”中的其他用户共享费用。对于每个组,我使用以下三个 blue 表: enter image description here

(请注意每个用户如何定义他们的份额金额以及共享费用的自己的类别。UserShare表使用复合主键。)

问题:我必须将用户与他们的3个个人“财务”表和3N“ SharedExpense”表(其中N是'用户所属的共享费用组)。

尝试的解决方案

  1. 多个数据库。每个用户的“财务”表都有一个唯一的数据库。每个“共享费用组”在服务器上都有一个唯一的数据库。然后,我可以将一个主数据库中的用户与以下四个紫色表相关联:
    Solution with multiple databases
    缺点:外键来自不同的数据库,需要备份大量数据库。

  2. 多个表。我可以在同一数据库中创建所有表,并将它们与四个 green 主表相关联: Solution with multiple tables
    在这里,表的数量是一个潜在的问题。如果有M个用户和N个“共享费用组”,那么将有3M + 3N个表!

问题:是否为此目的设计了更优雅,更简单的数据库?如果不是,那么以上两种解决方案中哪一种更好,为什么?

链接到相关的先前StackOverflow问答

1 个答案:

答案 0 :(得分:2)

在总结中要描述的所有挑战很多,但我将挑选其中一些。

  1. 基本设计违规:例如每个用户的表/数据库
  2. 实体设计,3NF:例如category.budget和ledger.transaction_type
  3. 参照完整性/关系设计:
    • 帐户用于一个用户,但是帐户表中不包含用户ID;
    • usershare是分类帐的子集,但它们都指向用户;
  4. 对象命名问题:
    • 基于真实用法的清晰一致的命名实体。成员是用户还是用户是成员?如果它们相同,则选择一个名称。如果它们不相同,则设计会有所不同。员工使用客户还是客户而不是会员?
    • 密钥命名的一致性。密钥名称应直接将其绑定到源实体。 Members.ID应该引用为members_id,而不是user_id。但是,在更正此错误之前,请先查看下一个条目。
    • 在您的实体中保持一致。普遍的共识是,该名称应描述一个记录(用户),而不是所有记录(用户)。
    • ledger.spent_on-该名称显然不是日期。它也可能指向用户或类别。属性名称应描述该属性,而无需其他说明。例如,ledger.Purchase_Date不言自明。还应该清楚它与实体的关系。 UserShare.Share并没有真正告诉我它包含的内容。

很抱歉,不过我会重新开始。考虑一下您的运行状况如何,然后再使用其他信息重新开始。

  • 询问您的设计问题(是否所有用户都是会员?所有会员都是用户吗?)。如果答案是“是”或“否”以外的其他答案,请进一步细分。
  • 尝试假设情况(如果共享分类帐超出类别预算该怎么办?如果类别预算发生变化,以前的支出将如何被感知?)
  • 考虑可能要询问哪些报告问题(谁超出了预算?我们在该类别上花费了多少?),然后考虑使用该问题回答该问题。

请阅读3NF以及一些更高的归一化水平。尽管3NF几乎是最小标准化,但更高的水平变得越来越专业化,可能不适用于您的设计。

您对数据和业务的了解越多,您的设计就会越好,最终产品就会越好。