4

我试图弄清楚当键基于类型指向不同的表时如何正确存储外键。

我进行搜索 , 但发现似乎没有任何 帮助

有一个表将存储学分的大部分基础知识:

user_accounting
--------------------
user_accounting_id      (PK)
user_id                 (FK)
amount              
type                    (+deposit, +credit, -transfer, -purchase)
credit                  (bool, so I don't have to always check if amount is < or > 0)
void                    (in case it was canceled and repaired with some other transaction)
date
details                 (notes)

类型

deposit - for outsite money being put into the system.
credit - are for money being transfered into their account from another
transfer - for putting money into someone elses account
purchase - for purchasing a site item

到现在为止还挺好。下一部分我有点困惑。它还必须存储资金的去向或来源。

我想存储表明它来自的任何类型的外键。因此,如果是购买,它将存储invoice_id的FK,如果是存款,它将存储来自商家提供商的transaction_id,如果是转账,它将存储信用的user_accounting_id,如果是信用,它会存储转账的 user_accounting_id。

我会很高兴有一个单列存储:

user_accounting (con't)
-----------------------------
source_or_destination_id (FK)

但我知道我不能让单个列成为基于type链接到不同表的外键。所以我可以将它存储为 (int) 但尝试使用该 id 与基于type的不同表进行 JOIN 将是一个巨大的痛苦。很久以前就尝试过,大错特错。

所以相反,我可以这样做:

user_accounting (con't)
-----------------------------
invoice_id                  (FK)
transaction_id              (FK)
credit_user_accounting_id   (FK)
transfer_user_accounting_id (FK)

但是这又是一个大问题,因为我创建了一个不好的独家弧。

我也可以对类型使用 many_to_many_through 关系,但数据透视表仍然存在将外键存储在多个表的同一位置的相同问题。

也许我可以简单地将不同类型的事务完全存储在不同的表中,我可以:

user_accounting_deposit, user_accounting_credit, user_accounting_transfer, user_accounting_purchase.

然后外键就不会有问题了。当然,要弄清楚任何人的帐户余额,我现在必须从一堆表中进行连接和求和。

也许有一种完全不同的更好的方法来做到这一点。我不在乎它需要多少张桌子。我很可能在某处使某些事情复杂化了。

谢谢

4

1 回答 1

1

500 多年来,簿记员一直在处理存储资金的来源和去向的问题。这就是他们发明复式记账法的原因。否则称为复式记帐。

您需要查看用于复式记账的数据模型。在您之前的程序员已经这样做了数千次。

如果您需要示例模型,请访问Database Answers并查看“Accounting Systems”下的内容。您应该能够获得涵盖您的案例的模型图。

于 2011-07-06T10:44:30.127 回答