ER图中的基数

Cardinality in ER diagram

我做了一个项目,它本质上是一个网上书店,人们可以在那里买书和下订单。

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

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

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

请帮我解决这个问题。

这是我的 EERD:

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

您需要更改设计,以便多个 user_order 行不可能引用同一个 shipping_address 行。

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

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

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

其他一些提示:

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