如何在 sql 数据库中正确实现商务数据关系?

Posted

技术标签:

【中文标题】如何在 sql 数据库中正确实现商务数据关系?【英文标题】:How can I properly implement commerce data relationships in a sql database? 【发布时间】:2011-09-14 19:11:16 【问题描述】:

首先,我想开始表达我并不是想让某人为我创建我的表架构。我花了一些时间在我的设计中权衡这两种可能性之间的选择,我想在我开始疯狂地使用我目前的想法之前获得一些建议。

这是我当前的架构,我会放一个 ?在我正在考虑使用的列旁边。

键:

table_name
----------
col1 | col2 | col3

tax_zone
---------
tax_zone_id | tax_rate | description

sales_order
-----------
sales_order_id | tax_zone_id (FK) or tax_rate (?)

sales_order_item
-----------
sales_order_item_id | sales_order_id (FK) | selling_price | amount_tax or tax_rate (?)

因此,如果还不清楚,那么难题是我是否应该将税收数据存储在订单的各个行中,或者使用连接来提取 tax_zone 信息,然后在我的查询中执行一些操作,例如(tz.tax_rate * so.order_amount) as order_total

目前,我正在考虑使用我刚才描述的方法。尽管我似乎无法弄清楚如何补救,但我看到这种方法存在一个问题。特定区域的税率可能会发生变化。这意味着,如果某个区域的税率发生变化并且我使用的是外键参考,则税率的变化将反映在过去使用不同税率完成的订单中。这会导致一个问题,因为目前我正在使用此表中的数据来存储已处理的订单和仍处于打开状态的订单,因此如果有人要重新打印过去的订单,订单的总金额会变的。

我存储特定税率或税额的问题在于,这意味着每次有人要编辑订单时,我都必须使用对这些值的更改再次更新该行。

在写这篇文章的过程中,我开始倾向于后一种想法,即两者中的佼佼者。

也许有人可以为我提供以下问题的答案,这样我就可以自己进行更多研究。

这是数据库建模中的一个已知问题吗? 是否有任何知名的“权威”发表过一本书/文章?

非常感谢任何帮助,谢谢!

【问题讨论】:

一个小问题:在欧洲,增值税率取决于所售商品(目前有两种:低增值税=4% 和高增值税=18% IIRC)。因此,“正在使用的税收类别/区域”列应从 sales_order 移至 sales_order_item 表。 感谢您的意见。我不知道欧洲的增值税设置。我们公司几乎只与美国客户打交道,不过我肯定会修改它。 【参考方案1】:

嗯,版本控制和历史是数据库建模中众所周知的问题。您的解决方案很常见。

对于像增值税税率这样的简单枚举,一个简单的“引用 taxtable(id) 的外键 tax_id”就可以了。 tax-table 永远不应该更新,一旦输入了 tax_id,它就应该永远保留在那里。如果年底税率发生变化,即使新值的记录已经存在,也应在 tax_table 中输入新记录。

搜索引擎的最佳搜索词组可能是“时态数据库”。

更新: http://www.google.nl/url?sa=t&source=web&cd=2&ved=0CCMQFjAB&url=http%3A%2F%2Fwww.faapartners.com%2Fdownloads%2Foverige-publicaties%2Fpresentatie-over-tijd-in-databases%2Fat_download%2Ffile&rct=j&q=veldwijk%20temporal&ei=HQdxTtimCcKr-QansM28CQ&usg=AFQjCNEg9puU8WR1KIm90voSDp13WmE0-g&cad=rja

【讨论】:

【参考方案2】:

在您描述的情况下,您最终必须将税率存储在订单表中,因为您需要关闭订单的税率。

因此,最简洁的解决方案必须是每次更新订单时计算税率,除非订单已关闭。您可以使用触发器来执行此操作。

(在我写这篇文章时,Ben 的答案突然出现了 - 似乎我们不同意,这可能没有帮助 :-)

【讨论】:

我认为这是要走的路。税收确实会发生变化,但您需要记住提交订单时收取的费率。同上任何可以改变的东西 - 产品价格,运输等。新订单的参考费率,但在提交时将它们复制/快照到每个订单。是的,您必须在每次编辑订单时不断更新订单,但在提交时“冻结”这些值。 @chrispanda 我们不反对!我会在订购时添加费率,但只是将费率存储在不同的表中。您还打算如何将其添加到订单表中? 你觉得@wildplasser 的想法怎么样?根据他的意见,我正在考虑类似的事情。我将有一个存储 tax_zone_id | 的表税率 |日期时间输入。我对提取 tax_rate 信息的查询将如下所示。 SELECT tr.tax_rate, so.sales_order_id FROM sales_order so JOIN tax_zone tz ON so.tax_zone_id = tz.tax_zone_id ,那么您将不得不原谅我缺乏即时 sql 知识,但查询的其余部分将影响输入日期的 tax_rate 我相信您应该始终尝试做可能可行的最简单的事情,因此我认为在这种情况下@wildplasser 的方法过于复杂。我认为将税款存储在订单表中作为 tax_zone 表的键没有任何价值,因为据我所知,这并没有带来任何好处,而且在检索订单时需要连接。为什么不在订单创建/更新时将应付税款放在订单表中?也就是说,我并不声称自己是这方面的专家,有人可能会想出一个为什么这不是一个好的解决方案的原因【参考方案3】:

2 分。您将不得不将税率存储在某个地方,否则您将无法将其添加到 sales_order 或其他任何地方。其次,税率会随时间变化,因此您不想每次都更新。

所以你有两个选择。

将税率存储在参考表中,并在输入表时使用正确的税率更新每个订单。

每次访问时计算所有内容。

个人我会选择选项 1,但在参考表中将开始时间作为主键的一部分,就好像您确实需要更改税率一样,您可能需要知道什么正确的汇率是下订单时的。

【讨论】:

以上是关于如何在 sql 数据库中正确实现商务数据关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PHP + MySQL 中正确实现自定义会话持久化器?

如何在核心数据中正确保存可转换对象?

如何在c#中正确实现等待异步[重复]

如何在python的类中正确实现辅助函数

在这种情况下,如何在 Flutter 中正确实现 FutureBuilder?

如何在php中正确实现结构化菜单