Являются ли моментальные снимки цен на позиции лучше, чем расчеты, во всех случаях?

StackOverflow https://stackoverflow.com/questions/1758889

Вопрос

Я часто видел таблицы line_item для заказов или счетов-фактур, которые копируют одно или несколько полей из других таблиц, чтобы сделать моментальный снимок заказа продукта клиента, когда он был размещен.

Однако в моей схеме я могу сгенерировать представление заказа без копирования данных.Таким образом, поиск данных о заказе / продукте / цене обходится немного дороже, но я экономлю время, пространство и избыточность при копировании / вставке.Я понимаю, что копирование / вставка - это одноразовая транзакция, тогда как поиск потребуется много раз - однако я имею дело только с 10 тысячами записей в данной таблице, и я не ожидаю, что производительность будет проблемой.

Итак, поскольку а) моя схема поддерживает точный поиск без мгновенного снимка, и б) у меня нет сильной потребности в поисковой оптимизации, я думаю, имеет смысл выполнить вычисление вместо мгновенного снимка.Или я чего-то не понимаю, и должен ли я всегда делать снимок в подобных случаях?

Вот пример того, как будет выглядеть поисковый расчет:

# 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)
Это было полезно?

Решение

В приложении для онлайн-продаж, над которым я работал, мы всегда копировали рассчитанные налоги и цены в каждый отдельный заказ при его размещении;это ваш вариант «снимка».Мы никогда его не пересчитывали.Почему?

  • Цены меняются;на снимке отражается цена на момент заказа продукта, а не ее цена сейчас.
  • Столы меняются.Вы полагаетесь на то, что каждый производитель и потребитель ваших цен будет знать о представлении и использовать только это представление.Навсегда.Если вы предоставите снимок, будущим потребителям данных будет все равно, как он был рассчитан.
  • Схемы меняются.Онтарио меняет способ расчета налога с продаж и продукты, облагаемые налогом.Это нарушает представление, но не снимок.
  • Правила меняются.Нам нужно было предоставить клиентам возможность обходить правила для таких вещей, как купоны и сопоставление цен.Вы можете сделать это, переопределив цену снимка, вы не можете сделать это с представлениями.

Другие советы

Обычно моментальные снимки делаются для того, чтобы было проще гарантировать, что у вас есть достоверный отчет о каждой продаже, будь то для хранения данных или для обработки жалоб клиентов.С моментальными снимками это просто вопрос обеспечения безопасности одной таблицы, создания резервных копий и строгого аудита.

Делая это по-своему, вы получаете такую гарантию намного сложнее, главным образом потому, что вы должны убедиться, что никто никоим образом не нарушил ни одну из задействованных таблиц (скидка, налог, продукт, заказ и так далее).Например, как бы вы определили, изменил ли кто-нибудь учетную ставку за январь 2005 года?Кроме того, это мешает вам легко развивать свою модель данных, что, если теперь вам нужно иметь более одного столбца для ставки дисконтирования, вам тогда придется не только изменять вычисления на будущее, но и сохранять старые для прошлого (или же выполнять каждое изменение обратно совместимым способом).

Пространство стоит дешево, наличие моментальных снимков упрощает многие вещи при небольших затратах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top