在所有情况下,订单项价格的数据快照是否都比计算结果更好?

发布于 2024-08-11 15:11:22 字数 1961 浏览 6 评论 0原文

我经常看到订单或发票的 line_item 表从其他表中复制一个或多个字段,以便在下达客户产品订单时拍摄快照。

但是,在我的架构中,我可以生成订单视图而无需复制数据。因此,查找订单/产品/价格数据有点贵,但我节省了复制/插入的时间、空间和冗余。我知道复制/插入是一次性事务,而查找需要多次 - 但是,我只处理给定表中的数十万条记录,并且我不期望性能一个问题。

因此,因为 a) 我的模式支持无需快照的准确查找,b) 我对查找优化没有强烈的需求,我认为运行计算而不是运行计算是有意义的拍摄快照。或者是否有我遗漏的东西,在这种情况下我应该总是拍摄快照?

以下是查找计算的示例:

# display order items for a particular order on a particular date

# get order, products and base prices from order_id

order_products = SELECT * FROM order_has_product ohp
                          INNER JOIN price ON (price.product_id = ohp.product_id)
                          INNER JOIN order ON (order.id = ohp.order_id)
                          WHERE order_id = ?


# calculate price of each product at order.datetime_opened

for op in order_products:

    tax = SELECT SUM(tax.rate) FROM product_has_tax pht
             INNER JOIN tax ON (tax.id = pht.tax_id)
             WHERE pht.product_id = op.product_id
                 AND tax.date_start <= op.datetime_opened
                 AND tax.date_end >= op.datetime_opened

    discount_product = SELECT SUM(discount.rate) FROM product_has_discount phd
             INNER JOIN discount ON (discount.id = phd.discount_id)
             WHERE phd.product_id = op.product_id
                 AND discount.date_start <= op.datetime_opened
                 AND discount.date_end >= op.datetime_opened

    discount_customer = SELECT SUM(discount.rate) FROM customer_has_discount chd 
             INNER JOIN discount ON (discount.id = chd.discount_id)
             WHERE chd.customer_id = op.customer_id
                 AND discount.date_start <= op.datetime_opened
                 AND discount.date_end >= op.datetime_opened
                 AND (chd.date_used_limited IS NULL OR chd.date_used_limited = op.datetime_opened)

    discount = discount_product + discount_customer

    price = op.price * (1-discount) * (1+tax)

I've often seen line_item tables for orders or invoices that copy one or more fields from other tables in order to take a snap-shot of a customer's product order when it was placed.

In my schema, however, I can generate a view of an order without copying data. So looking up the order/product/price data is a little more expensive, but I save time, space and redundancy on the copy/insert. I understand the copy/insert is a one-time transaction, whereas the look-up will be required many times - however, I'm only dealing with 10s of thousands of records in a given table and I don't expect performance to be an issue.

So, because a) my schema supports an accurate look-up without a snap-shot, and b) I don't have a strong need for look-up optimization, I think it makes sense to run a calculation instead of taking a snap-shot. Or is there something I'm missing and should I always take a snap-shot in cases like this?

Here's an example of what the look-up calculation would look like:

# display order items for a particular order on a particular date

# get order, products and base prices from order_id

order_products = SELECT * FROM order_has_product ohp
                          INNER JOIN price ON (price.product_id = ohp.product_id)
                          INNER JOIN order ON (order.id = ohp.order_id)
                          WHERE order_id = ?


# calculate price of each product at order.datetime_opened

for op in order_products:

    tax = SELECT SUM(tax.rate) FROM product_has_tax pht
             INNER JOIN tax ON (tax.id = pht.tax_id)
             WHERE pht.product_id = op.product_id
                 AND tax.date_start <= op.datetime_opened
                 AND tax.date_end >= op.datetime_opened

    discount_product = SELECT SUM(discount.rate) FROM product_has_discount phd
             INNER JOIN discount ON (discount.id = phd.discount_id)
             WHERE phd.product_id = op.product_id
                 AND discount.date_start <= op.datetime_opened
                 AND discount.date_end >= op.datetime_opened

    discount_customer = SELECT SUM(discount.rate) FROM customer_has_discount chd 
             INNER JOIN discount ON (discount.id = chd.discount_id)
             WHERE chd.customer_id = op.customer_id
                 AND discount.date_start <= op.datetime_opened
                 AND discount.date_end >= op.datetime_opened
                 AND (chd.date_used_limited IS NULL OR chd.date_used_limited = op.datetime_opened)

    discount = discount_product + discount_customer

    price = op.price * (1-discount) * (1+tax)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幻梦 2024-08-18 15:11:22

在我开发的在线销售应用程序中,我们总是在下单时将计算出的税费和价格复制到每个单独的订单中;这是您的“快照”选项。我们从未重新计算过。为什么?

  • 价格变化;快照捕获的是订购产品时的价格,而不是现在的价格。
  • 表格发生变化。您依赖价格的每个生产者和消费者来了解视图并仅使用视图。永远。如果您提供快照,未来的数据使用者就不会关心它是如何计算的。
  • 模式发生变化。安大略省正在改变计算销售税的方式以及对哪些产品征税。这会破坏视图,但不会破坏快照。
  • 规则改变。我们必须为客户提供一种方法来推翻优惠券和价格匹配等规则。您可以通过覆盖快照价格来做到这一点,但不能通过视图来做到这一点。

In the online sales application I worked on, we always copied calculated taxes and prices to each individual order when it was placed; this is your "snapshot" option. We never recalculated it. Why?

  • Prices change; the snapshot captures the price at the time the product was ordered, not what it is now.
  • Tables change. You are relying on every producer and consumer of your prices to know about the view and use only the view. Forever. If you provide the snapshot, future data consumers don't care how it was calculated.
  • Schemas change. Ontario is changing how it calculates sales tax and what products are taxed. This breaks the view, but not a snapshot.
  • Rules change. We had to provide a way for clients to override rules for things like coupons and price-matching. You can do this by overriding the snapshotted price, you can't do it with views.
潜移默化 2024-08-18 15:11:22

通常,拍摄快照是为了轻松确保您拥有每次销售的忠实记录,无论是用于数据仓库还是用于客户投诉处理。使用快照,只需保持单个表的安全、备份并进行严格的审核即可。

按照你的方式去做会让保证变得更加困难,主要是因为你必须确保没有人以任何方式弄乱任何涉及的表(折扣、税收、产品、订单等)。例如,您如何判断有人更改了 2005 年 1 月的折扣率?此外,这会阻止您以简单的方式发展数据模型,如果您现在必须有多个折扣率列,那么您不仅需要更改未来的计算,而且还需要保留旧的计算对于过去(或者以向后兼容的方式进行所有更改)。

空间很便宜,拥有快照可以使很多事情变得更容易,并且成本很低。

Usually snapshots are taking to make it easy to insure you have a faithful record of each sale, be it for datawarehousing or for customer complaint handling. With snapshots it's just a matter of keeping a single table safe, backed up and with strict auditing.

Doing it your way makes having that guarantee a lot harder, mainly because you have to ensure nobody has messed in any way with any of the involved tables (discount, tax, product, order and so on). For example, how would you tell if somebody changed the discount rate for the january 2005? Additionally, this prevents you from evolving your data model in an easy way, what if you now have to have more than one column for the discount rate, you would then not only have to change the calculations for the future but to keep the old ones for the past (or else do every change in a backwards compatible way.)

Space is cheap, having snapshots makes lots of things easier, at a small cost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文