发票数据库设计

Posted

技术标签:

【中文标题】发票数据库设计【英文标题】:Invoicing database design 【发布时间】:2012-01-29 10:49:06 【问题描述】:

我几天前创建了一个处理发票的应用程序。我想知道如何最好地将折扣整合到我的发票中。我应该把它作为一个否定项(在 invoice_items 表中)还是应该在发票表中创建一个“折扣”列?

【问题讨论】:

这两种选择中的任何一种都会对您产生什么影响?例如,您希望以后有多个折扣,还是非常具体的折扣? 感谢您的快速回复。每张发票只有一个折扣。 如果每张发票只有一个折扣,那么我不会让它变得比需要的更复杂。 那么我应该把它放在哪里呢?在发票表上或将其添加为否定项? 抱歉不清楚。在我看来,将它放在发票表中会更容易、更清晰——我认为,将其作为负项会使项目的处理更加困难。 【参考方案1】:

我会把它作为一个负值项目。原因是:

在开票时,计算值永远保持不变是非常重要的;即使您的计算公式稍后发生变化,您也可以正确复制任何给定的发票。如果当时计算的值不正确也是如此 - 它就是这样。 具有价值金额意味着可以轻松处理针对特殊情况的手动调整 - 例如,您的营销经理/会计师可能会因为延迟交货而决定给予 100 美元的一次性折扣。这对于负值来说是微不足道的 - 只需添加另一行,但折扣率很困难/麻烦 每张发票可以有多个折扣金额 它完全灵活——它有自己的空间存在,可以随心所欲。事实上,我会将折扣打造成另一种“产品”(甚至可能是多种产品 - 一个针对每个不同的折扣原因,例如圣诞节、优惠券、推荐等)。 对于自己的项目,您可以像任何其他“产品”一样添加原因描述 - 例如“支付现金 10% 折扣”或其他任何内容 您不需要任何特殊的代码或数据库列!只需像以前一样汇总项目并将它们打印在发票上。 “没有勺子(折扣)”:这只是另一个订单项 - 还有什么比不需要更改代码/数据库更简单的呢? 并非所有商品都应打折 - 例如退款、退货、订阅(如果适用)。它变得太复杂了,没有必要在数据库中表示折扣的业务逻辑。将计算等留在应用程序代码中,将结果存储在数据库中 拥有自己的项目意味着计算可以任意复杂。这意味着随着复杂性的增加无需维护数据库。维护/更改代码比维护/更改数据库要容易得多 最后,我成功搭建了一个发票系统,并且采用了“item”的方式,效果非常好

【讨论】:

+1,但仅此而已。这里提出了很多好的观点,但我不确定我是否同意整个结论。这可能取决于进行开发票的行业。发票的稳定性是关键;这可能会通过确保价格数据(特别是产品描述等)在发票时是准确的(可能通过将产品表中的相关数据复制到发票项目表中,或类似的东西来处理) )。为一次性 100 美元折扣之类的东西设置“特殊产品代码”就可以了。 [...继续...] [...continuation...] 但是,我认为仅通过特殊项目处理折扣是错误的;商品通常有折扣,并且可以与商品一起记录为百分比或金额。如果有整体折扣,则可以与主发票一起记录。在这两种情况下,都不需要 NULL 来记录没有折扣;零值通常是适当的默认值(除非确实是标价例外)。 @JonathanLeffler 你提出了很好的观点。如果有很多折扣,那么也许你是对的。但是,当列已定义但很少使用时,即折扣不是常态时,您最终会得到“稀疏”数据,这对我来说是一个设计“危险信号”。 很公平 - '正在开发票的行业' 大约相当于'如果有很多折扣';就是要根据实际使用情况来做决定。我怀疑通用会计软件包(可以针对许多不同系统进行定制)将允许我们概述的所有选项,因为我相信它们都用于会计世界的不同部分。【参考方案2】:

这两种选择中的任何一种都会对您产生什么影响?例如,您希望以后有多个折扣,还是非常具体的折扣?如果每张发票只有一个折扣,那么我不会让它变得比需要的更复杂。在我看来,将它放在发票表中会更容易、更清晰——我认为,将其作为负数项目会使项目的处理更加困难。

【讨论】:

我同意您的回答,当客户决定他可能希望在未来获得多个折扣时,我正要这样做。因此我不得不使用 item 方法。【参考方案3】:

我完全同意让它尽可能简单,但要考虑的一件事是,是否有任何商品应免于折扣?在这种情况下,您需要在详细信息中添加一个 bool 字段来记住哪一行应该有折扣。

【讨论】:

以上是关于发票数据库设计的主要内容,如果未能解决你的问题,请参考以下文章

为应收账款寻找简单的数据库设计[关闭]

设计具有混合粒度的事实表

订单/发票/付款数据库建模

产品场景梳理方法与基于场景的产品设计方法

数据库设计——谷歌应用引擎

使用 JOIN 而不是 NOT IN 优化 SQL 查询