Как я могу заполнить значение внешнего ключа после создания первой записи таблицы, на которую ссылается внешний ключ? - PullRequest
0 голосов
/ 04 апреля 2020

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

  1. Пользователи
  2. Продукты
  3. Заказы
  4. Cart_Items

Я получил следующую схему: image

Для схемы выше, давайте рассмотрим, у меня есть набор пользователей и набор продуктов. Каждый пользователь может добавлять товары в свою корзину и размещать заказ в любое удобное для них время.

Строка в таблице Cart_Item представляет одну запись в таблице Product, которую пользователь решил добавить в корзину. Пользователь может добавить столько товаров в корзину, сколько он будет sh.

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

Мой логин c имеет недостатки, так как для каждого товара, который я добавляю в корзину, мне нужно указать OrderID, частью которого он является. Но есть этап, когда в корзине есть товары, и заказ еще не сделан. Когда заказ размещен, мне нужно передать OrderID обратно на продукты в таблице Cart_Item, но нет способа их идентифицировать. Как я могу установить связь между заказом, который был недавно размещен, и продуктами, которые содержались в этом заказе?

Мне не хватает чего-то огромного, но я не могу это понять.

Ответы [ 2 ]

0 голосов
/ 06 апреля 2020

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

Если вышеприведенное верно и учитывая, что пользователь не может работать с несколькими заказами одновременно, вы можете использовать две таблицы, подобные этой (значения 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 и ваши бизнес-требования, но я думаю, что было бы лучше использовать эту таблицу только для повторного заполнения текущей корзины вашего пользователя в пользовательском интерфейсе. Оставьте действие «отправить заказ» отдельно и отправьте полный список продуктов для отправки в качестве заказа.

0 голосов
/ 06 апреля 2020

Добавить еще одну таблицу для OrderStatus. OrderStatus будет содержать действительные значения.

OrderStatus
-----------
   OrderStatusID
   OrderStatusName: New, Sent, Shipped, Completed, ...

Order
-----
   OrderStatusId: FK OrderStatusId

Таким образом, когда пользователь добавляет первый товар в свою корзину, создайте Order с OrderStatus, установленным в New. Это обрабатывается вашим приложением.

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