Являются ли моментальные снимки цен на позиции лучше, чем расчеты, во всех случаях?
-
20-09-2019 - |
Вопрос
Я часто видел таблицы 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 года?Кроме того, это мешает вам легко развивать свою модель данных, что, если теперь вам нужно иметь более одного столбца для ставки дисконтирования, вам тогда придется не только изменять вычисления на будущее, но и сохранять старые для прошлого (или же выполнять каждое изменение обратно совместимым способом).
Пространство стоит дешево, наличие моментальных снимков упрощает многие вещи при небольших затратах.