Когда делать расчеты - PullRequest
       25

Когда делать расчеты

9 голосов
/ 24 февраля 2010

Какой способ лучше хранить информацию о продажах в базе данных:

  1. Стоимость магазина за товар и цена продажи за товар
  2. Стоимость магазина * Кол-во и цена продажи * Кол-во - поэтому вы сохраняете итоги в БД

Ответы [ 7 ]

7 голосов
/ 24 февраля 2010

Храните все отдельные данные для каждого элемента, так как они вам обычно понадобятся позже (для статистических / информационных целей или по любым другим причинам). Вы должны убедиться, что вы всегда следуете той же логике расчета, чтобы получить общую цену продажи. Таким образом, вам, возможно, придется хранить валюты, скидки, ценовые единицы и т. Д. Вместе с ними. Вот еще несколько моментов для рассмотрения:

  • Если вы хотите вывести цену одного элемента позже, вам нужны данные одного элемента.

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

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

6 голосов
/ 24 февраля 2010

Это проблема 3-я нормальная форма .

Вариант 1 в 3-й нормальной форме. Там нет производных данных. Расчет должен быть сделан для каждого запроса. Из-за этого обновления могут быть сделаны на любом поле, ничего не нарушая.

Вариант 2 разрывает 3-ю нормальную форму. Сохраняет полученные данные. Расчеты не выполняются во время запроса, что делает их намного быстрее. Однако обновление, которое также не повторяет вычисления, приведет к противоречивым данным. Это называется «аномалия обновления». В результате обновления поле производных данных стало несогласованным.

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

1 голос
/ 25 февраля 2010

Это зависит от того, что вы собираетесь делать с данными.

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

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

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

«предметы» обычно являются детьми какой-то более крупной единицы работы. В системе выставления счетов товар является частью счета. В системе Главной книги элемент является частью транзакции. Элементы не сбалансированы, но сделка есть. В наши дни во многих коммерческих системах функции выставления счетов и учета ведутся из одной и той же базы данных, но это выходит за рамки вашего вопроса.

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

0 голосов
/ 24 февраля 2010

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

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

0 голосов
/ 24 февраля 2010

ИМХО стоимость магазина и продажи за единицу. Если вы хотите, чтобы результаты были похожи на итоги, либо выполните их внутри запроса, либо создайте временную таблицу или хранимую процедуру с вычислениями. Тем не менее, я обычно выполняю эти вычисления в коде (в моем случае PHP или JAVA). Если это только для целей отчета, иногда удобно хранить итоги для ускорения вычислений (и предотвращения некоторых неправильных вычислений в вашем коде).

0 голосов
/ 24 февраля 2010

Я бы пошел с сохранением стоимости товара и продажной цены товара. Если вы храните только итоги, вам будет сложно пересчитать ваши значения, если цены изменятся. Представьте себе, что вы предоставляете сезонную скидку на некоторые из ваших товаров, применяете различные налоги к некоторым товарам (возможно, даже разные, в зависимости от страны происхождения клиента) или предоставляете более низкие цены для зарегистрированных клиентов - вам придется рассчитывать эти цены на основе продаж цена товара, итоги в этом случае бесполезны.

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

0 голосов
/ 24 февраля 2010

Я бы сказал, что вы всегда сохраняете стоимость и цену в виде отдельных столбцов И сохраняете общее количество. Будет время, когда вам понадобятся те, у кого возникнут проблемы (отчетность, выставление счетов), о которых вы пожалеете.

Вопрос действительно возникнет, если вы сохраните рассчитанные значения. это действительно будет зависеть от обстоятельств приложения (сколько строк, сколько транзакций и т. д.). Если это приложение среднего размера, это, вероятно, не повлияет на производительность, поэтому это просто вопрос других факторов.

Если формула для суммы может стать более сложной (например, налоги, скидки и т. Д.), Вы можете сохранить сумму. в противном случае копирование этой логики в других областях может оказаться чрезвычайно трудным.

Лично я всегда храню общую сумму. Я просто нахожу, что стоимость дополнительного столбца базы данных всегда перевешивается из-за того, что эта сумма в других местах.

...