Если я правильно понимаю, вы хотите сохранить текущий выбор продуктов пользователем, например, он может закрыть сеанс и возобновить его позднее? Если это не так, вы можете просто сохранить продукты заказа, когда заказ будет отправлен.
Если вышеприведенное верно и учитывая, что пользователь не может работать с несколькими заказами одновременно, вы можете использовать две таблицы, подобные этой (значения PK каждой таблицы находятся над пунктирной линией):
[UserCart]
########################
# userId #
# productId #
# -------------------- #
# quantity #
########################
[OrderProduct]
########################
# orderId #
# productId #
# -------------------- #
# quantity #
########################
UserCart
представляет продукты, которые в настоящее время находятся в корзине пользователя.
- Использование другого искусственного ПК, такого как
cartItemId
, ничего не предлагает, заставляя вас делать дополнительные необходимые проверки, чтобы избежать ошибок. ПК (UserId
, ProductId
) предлагает вам необходимые ограничения бесплатно. - Вы запрашиваете эту таблицу, чтобы заполнить корзину вашего пользователя.
- Вы сохраняете любые изменения по мере необходимости.
- Вы очищаете корзину, когда заказ отправлен, как считаете нужным (удаляя строки для указанного c
userId
или устанавливая количество в 0, если подходите к нему по-другому)
OrderProduct
представляет продукты, содержащиеся в пользовательском отправленном заказе. Когда пользователь отправляет заказ, вы выполняете транзакцию, которая:
- Вставляет новый заказ в таблицу
Order
, из которой вы получаете orderId
- Вставить строку в
OrderProduct
для каждого продукта в заказе с соответствующим количеством. - Не думаю, что вам следует указывать цену здесь, так как ее легко запросить из таблицы
Product
. Если вы сделаете это в случае будущих изменений в ценах на продукты, было бы более целесообразно сохранить его в виде дополнительной таблицы истории, в которой хранятся все прошлые значения. Вы можете найти более подробную информацию здесь
PS Я бы попросил разъяснений, прежде чем отправлять ответ, но у меня нет необходимой репутации. Если я что-то не так, сообщите мне в комментариях.
Ответ на комментарии
Вы сказали, что OrderProduct является таблицей для всех выполненных заказов.
Я этого не говорил. Проверьте этот пример данных, чтобы его было легче понять:
##### User ######
| UserId | .... |
-----------------
| 1 | .... |
| 2 | .... |
########## Order ##########
| OrderId | UserId | .... |
---------------------------
| 1 | 1 | .... |
| 2 | 1 | .... |
| 3 | 2 | .... |
########## OrderProduct ##########
| OrderId | ProductId | Quantity |
----------------------------------
| 1 | 1 | 15 |
| 1 | 3 | 66 |
| 2 | 1 | 153 |
| 3 | 1 | 7 |
| 3 | 2 | 8 |
| 3 | 3 | 13 |
###### Product #####
| ProductId | .... |
--------------------
| 1 | .... |
| 2 | .... |
| 3 | .... |
| 4 | .... |
Ваши заказы имеют отношение многих к вашим продуктам. Более конкретно:
- Заказ содержит товары «один ко многим» (пустой заказ не может быть)
- Товар может содержаться в заказах «нуля ко многим» ( может быть, никто не заказывал продукт до того времени)
Таблица OrderProduct
реализует это отношение «многие ко многим»
Тогда не будет ли это отображать ордер таблица избыточна? Не могу ли я сгенерировать новую строку в таблице OrderProduct при отправке заказа с элементами моей корзины? Если это так, то у меня останется 4 таблицы, как это.
Может быть, пример выше проясняет некоторые вещи. Кроме того, я не понимаю, насколько вам нужно как можно меньше таблиц, но я не думаю, что это поможет вам правильно смоделировать ваши требования. Таблица ORDERPRODUCT
в ссылке просто неверна.
- Что представляет собой
orderId
PK? Если это просто автоинкрементный идентификатор каждой строки, единственная информация, содержащаяся в таблице, состоит в том, что пользователь X когда-либо заказывал Y единиц продукта Z. - Вы опускаете все дополнительные данные, которые изначально были в
Order
стол, date
и details
. Вы не можете добавить их, даже если хотите, потому что не можете идентифицировать там заказ, и даже если бы вы могли, вам придется повторять эти данные для каждого продукта в заказе.
I угадайте, если удаление таблицы так важно, и вам не нужно хранить дополнительную информацию о заказе, вы можете опустить таблицу Order
и структурировать OrderProduct
как:
[OrderProduct]
########################
# OrderDatetime #
# UserId #
# ProductId #
# -------------------- #
# Quantity #
########################
В этом случае, порядок будет определяться парой (UserId
, OrderDatetime
), но под идентификатором я имею в виду только теоретически, у вас не будет конкретной Order
сущности, на которую можно сослаться. Не думаю, что это хорошая практика, и, скорее всего, она сделает вашу жизнь труднее в других аспектах приложения без всякой причины.
Как я могу отправлять записи из UserCart в OrderProduct, если между ними нет таблицы соединений? Или таблица User будет выступать в качестве посредника между ними, делая возможным объединение?
Нет никакого объединения, связанного с вашим вопросом, вы можете получить текущие продукты в корзине пользователя с помощью простого выбора. оператор типа:
SELECT productId, quantity FROM UserCart WHERE userId = @userId
Вы можете использовать данные так, как вам удобно, например, вы можете использовать оператор INSERT INTO SELECT для того, что вы спрашиваете.
Это зависит от того, как вы используете таблицу UserCart и ваши бизнес-требования, но я думаю, что было бы лучше использовать эту таблицу только для повторного заполнения текущей корзины вашего пользователя в пользовательском интерфейсе. Оставьте действие «отправить заказ» отдельно и отправьте полный список продуктов для отправки в качестве заказа.