【发布时间】:2011-02-10 09:10:06
【问题描述】:
我正在为特许经营的 CRM 设计关系数据库的第二次主要迭代(进行了大量重构),我需要有关存储工作发票和的最佳数据库设计实践的帮助发票行,对每张发票所做的任何更改都有强大的审计跟踪。
当前架构
Invoices表
InvoiceId (int) // Primary key
JobId (int)
StatusId (tinyint) // Pending, Paid or Deleted
UserId (int) // auditing user
Reference (nvarchar(256)) // unique natural string key with invoice number
Date (datetime)
Comments (nvarchar(MAX))
InvoiceLines表
LineId (int) // Primary key
InvoiceId (int) // related to Invoices above
Quantity (decimal(9,4))
Title (nvarchar(512))
Comment (nvarchar(512))
UnitPrice (smallmoney)
修订架构
InvoiceRevisions表
RevisionId (int) // Primary key
InvoiceId (int)
JobId (int)
StatusId (tinyint) // Pending, Paid or Deleted
UserId (int) // auditing user
Reference (nvarchar(256)) // unique natural string key with invoice number
Date (datetime)
Total (smallmoney)
架构设计注意事项
1。存储发票的已付款或待处理状态是否明智?
收到的所有发票付款都存储在Payments 表中(例如现金、信用卡、支票、银行存款)。如果与给定工作的发票相关的所有收入都可以从Payments 表中推断出来,那么在Invoices 表中存储“已支付”状态是否有意义?
2。如何跟踪发票行项目修订?
我可以通过将状态更改连同发票总数和审计用户存储在发票修订表中来跟踪发票的修订(参见上面的InvoiceRevisions),但是跟踪发票行修订表感觉很难维护。想法? 编辑:订单项应该是不可变的。这适用于“草稿”发票。
3。税收
在存储发票数据时,我应该如何纳入销售税(或 SA 中的 14% 增值税)?
编辑:反馈很好,伙计们。 根据定义,发票和发票行是不可变的,因此跟踪更改是不明智的。但是,一张“草稿”发票在开具前必须可由多人编辑(例如,经理在技术人员创建发票后应用折扣)...
4。定义和跟踪发票状态的最佳方式?
- 草稿
- 已发布
- 作废
...被限制在一个方向改变?
【问题讨论】:
-
这听起来像是一个愚蠢的问题,但为什么要跟踪发票的更改呢?发票往往是不可变的东西,它代表完整的购买/合同;如果上面有错误,则将其作废并创建一个新的。
-
+1 @Aaronaught:很好,但是必须有某种形式的起草机制,因为发票可以由多个用户更新(例如,技术人员创建它并且经理在将其签发给之前应用折扣)客户)。可以说,这应该由不同的数据结构来处理。我考虑以这种方式跟踪更改的原因是因为发票(在旧模型中)具有状态(待处理、已支付、已删除)并且用户对更新它的人感兴趣(经理开始通过已支付发票跟踪技术人员的绩效,这也是不好的做法)。
-
有趣的是,您没有 products 表。产品/服务有那么独特吗?
-
看看这个问题:stackoverflow.com/questions/163517/… 和 Fowler 的文章martinfowler.com/apsupp/accounting.pdf
-
由于发票在定义上是不可变的,因此如果订单项更改或稍后添加折扣,我会选择作废发票并创建新发票。
标签: sql-server database-design invoices