Мощность на диаграмме ER

Я сделал проект, который по сути представляет собой книжный интернет-магазин, где можно купить книги и оформить заказ.

Моя база данных содержит различные таблицы, такие как:

  • user
  • user_shipping_address
  • user_payment_mode
  • user_order
  • order_shipping_address
  • order_billing_address
  • order_payment_details

Я попытался построить для этого диаграмму EERD, но меня смущает одна вещь: user_order может иметь только один адрес доставки. Я создал внешний ключ order_id в таблице order_shipping_address, который ссылается на первичный ключ order.id. У меня также есть внешний ключ shipping_address_id в таблице order, который ссылается на order_shipping_address.id.

Когда я пытаюсь создать диаграмму ER, она дает мне два разных отношения. Связь 1:1 между order и адресом доставки и связь 1:M между адресом доставки и заказом. Я не знаю, как структурировать ограничения внешнего ключа, потому что мне кажется, что таблица заказов должна содержать shipping_address_id, а адрес доставки должен содержать order_id, верно? Это только сделало все еще более запутанным.

Пожалуйста, помогите мне в этом.

Вот мой EERD: введите здесь описание изображения


person Sarthak Sachdeva    schedule 19.06.2017    source источник


Ответы (1)


Это происходит потому, что ваш текущий дизайн означает, что несколько строк user_order могут ссылаться на одну и ту же строку shipping_address.

Вам нужно изменить дизайн, чтобы несколько user_order строк не могли ссылаться на одну и ту же shipping_address строку.

Есть по крайней мере два различных возможных решения:

  1. Добавьте ограничение UNIQUE на user_order.shipping_address_id
  2. Or: invert the relationship (this my preferred option as it eliminates unneeded surrogate keys):
    1. Remove the user_order.shipping_address_id column.
    2. Измените shipping_address.id на shipping_address.order_id, чтобы это был внешний ключ user_order.id.
    3. Сделайте shipping_address.order_id новым первичным ключом shipping_address.

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

Несколько других советов:

  • Рассмотрите возможность использования int, а не bigint для ваших идентификаторов - я сомневаюсь, что у вас будет более 2 миллиардов строк в каждой таблице.
  • Не используйте вслепую varchar(255) для всех текстовых столбцов — используйте его, чтобы ввести разумные ограничения на длину данных, например, state не должно быть длиннее 2 символов, если вы храните сокращения, то же самое можно сказать и о zipcode, которое может быть varchar(10), если вы повторно используя ZIP+4.
  • НЕ ХРАНИТЕ ПОЛНЫЕ НОМЕРА КРЕДИТНЫХ КАРТ В СВОЕЙ БАЗЕ ДАННЫХ! (как показано в вашей таблице payment) — это нарушение правил PCI, огромная ответственность и, возможно, незаконная халатность в вашей юрисдикции. Ваш платежный процессор предоставит вам заменяющее непрозрачное значение токена (или что-то подобное) в качестве средства идентификации платежных карт и применения будущих платежей к сохраненным платежным реквизитам — максимум, что вы можете разумно хранить, — это последние 4 цифры. Независимо от того, шифруете ли вы данные, в значительной степени не имеет значения.
person Dai    schedule 19.06.2017