0

我做了一个项目,本质上是一个在线书店,人们可以在其中购买书籍并下订单。

我的数据库包含各种表,例如:

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

我试图为此构建 EERD 图,但我对一件事感到困惑:Auser_order只能有一个送货地址。我order_idorder_shipping_address表中创建了一个引用主键的外键order.id。我在表中也有一个引用的shipping_address_id外键。orderorder_shipping_address.id

当我尝试生成 ER 图时,它给了我两种不同的关系。与送货地址之间的关系为 1:1 order,送货地址与订单之间的关系为 1:M。我不知道如何构造外键约束,因为我觉得订单表应该包含shipping_address_id并且送货地址应该包含order_id,对吧?这只会让一切变得更加混乱。

请帮我解决这个问题。

这是我的 EERD:在此处输入图像描述

4

1 回答 1

0

发生这种情况是因为您当前的设计意味着多user_order行可以引用同一shipping_address行。

您需要更改设计,以使多user_order行无法引用同一shipping_address行。

至少有两种不同的可能解决方案:

  1. 添加UNIQUE约束user_order.shipping_address_id
  2. 或者:反转关系(这是我的首选选项,因为它消除了不需要的代理键):
    1. 移除user_order.shipping_address_id列。
    2. 更改shipping_address.idshipping_address.order_id,使其成为 的外键user_order.id
    3. 制作shipping_address.order_id的新主键shipping_address

请注意,这两个选项都是非规范化的,因为它可以防止在不同订单之间共享送货地址(例如,如果同一客户多次重复订购相同的订单),尽管这可能是故意的 - 因此,如果用户未来的地址发生变化,它就赢了'不会无意中追溯更新旧的订单发货记录。

其他一些提示:

  • 考虑使用int而不是bigint用于您的身份 - 我怀疑每个表中将有超过 20 亿行。
  • 不要盲目地varchar(255)用于所有文本列 - 使用它来强制对数据长度进行合理限制,例如state,如果您存储缩写,则不需要超过 2 个字符,zipcode如果varchar(10)您使用 ZIP+ 则同上4.
  • 不要在您的数据库中存储完整的信用卡号码!(如您的payment表中所示) - 这违反了 PCI 规则,在您的管辖范围内是一项巨大的责任和可能的非法疏忽。您的支付处理器将为您提供一个替代的不透明令牌值(或类似的东西),作为识别收费卡并将未来费用应用到存储的支付详细信息的一种方式 - 您可以合理存储的最多是最后 4 位数字。您是否加密数据在很大程度上无关紧要。
于 2017-06-19T23:30:25.233 回答