Во всех ли случаях моментальные снимки данных о ценах отдельных позиций лучше, чем расчеты? - PullRequest
1 голос
/ 18 ноября 2009

Я часто видел таблицы 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)

Ответы [ 2 ]

5 голосов
/ 18 ноября 2009

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...