Deonisius
@Deonisius
Родился в 11110110111 году, 11000 января.

Как правильно хранить данные заказов в БД?

Приветствую! Появился вопрос о рациональном хранении данных заказов с учетом быстрого поиска по разным параметрам. Планируется создание двух таблиц: общая информация о заказе (`orders`) и списки заказываемых товаров (`order_list`). C одной стороны, в `order_list` достаточно хранить id-заказа, id-товара, количество и цену. Но будет нужен поиск заказа по разным параметрам. К примеру, Вася Пупкин сообщает, что заказывал 10 штук "Ferrari F12 Berlinetta" и не указывал ни своего имени, ни каких-то других данных. То есть, нужно искать по названию в таблице товаров (`products`), связывая запрос с таблицей `order_list`. А не логично ли просто дублировать название товар сразу в таблицу `order_list`? То же касается и имени заказчика, и некоторых других данных, которое можно дописать к данным в таблицу (`orders`), а не хранить только id заказчика или id других параметров, по которым планируется поиск. Я прекрасно понимаю, что если в той же таблице `products` изменить название товара, то будет несостыковка с названием в заказах. Однако, можно же создать тот же триггер, который будет синхронизировать значения и такая операция - это единичные редкие случаи, а вот поиск - это ежедневный многократный процесс. В общем, хотелось бы услышать мнения сообщества по этому поводу.
  • Вопрос задан
  • 1105 просмотров
Пригласить эксперта
Ответы на вопрос 4
Stalker_RED
@Stalker_RED
Нет, дублировать данные в реляционной БД - не логично. Про нормализацию есть много умных книжек, но общее представление можно составить и по википедии.

Денормализация применяется в тех случаях, когда очень-очень нужно что-то оптимизировать.
habrahabr.ru/post/64524
habrahabr.ru/post/103021

Если вам очень хочется складывать всё в одну кучку посмотрите в сторону no-sql баз. MongoDB, и сородичи, например.
Ответ написан
@skvot
Подобное дублирование именуется денормализацией, уместно ли оно в конкретном случае - решать вам исходя из потребностей системы.
Зачастую уместно.
Плюсы:
- Ускоряется поиск
Минусы:
- Замедляется вставка
- Увеличивается занимаемый данными объем
- Затраты на поддержание корректности копий данных
Ответ написан
Однако, можно же создать тот же триггер, который будет синхронизировать значения и такая операция - это единичные редкие случаи, а вот поиск - это ежедневный многократный процесс.

Проще = надежней. Ни к чему логику размазывать на БД, поверьте. Процедуры в крайнем случае, когда high load.

Опять же стоит посмотреть в сторону понятия нормализации БД. Нормализация ради нормализации не нужна, но стоит придерживаться по возможности, нормализованную БД реально проще и приятней сопровождать в будущем, чем таблицы с околодесятком строк.
Ответ написан
Я бы в данном случае вынес название товара из products в отдельную таблицу pruduct_names со следующей структурой:
- id
- product_id
- name
- datetime
Таким образом, при обновлении названий товаров мы просто добавляем запись в pruduct_names, и если нужно узнать актуальное название товара:
SELECT name FROM pruduct_names WHERE product_id=? ORDER BY id DESC LIMIT 1

Если нужно узнать как назывался товар в момент заказа - делаем запрос:
SELECT name FROM pruduct_names WHERE product_id=? AND datetime<ORDER_DATE ORDER BY id DESC LIMIT 1

, где ORDER_DATE - дата заказа

Аналогично с данными пользователя (если эти данные у вас "одноразовые" - только для одного заказа), которые также можно запихать в отдельную таблицу (orders_data):
- id
- order_id
- type_id //ID из таблицы orders_data_types
- value
И связанную таблицу с типами данных для заказа (orders_data_types):
- id
- name
Таким образом в orders_data мы будем хранить только указанную информацию пользователя
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы