ER图中的基数

时间:2017-06-19 23:19:49

标签: mysql entity-relationship entity-relationship-model

我做了一个基本上是在线书店的项目,人们可以在那里买书并下订单。

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

  • 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的{​​{1}}外键。

当我尝试生成ER图时,它给了我两种不同的关系。 order_shipping_address.id和送货地址之间的1:1关系以及从送货地址到订单的1:M关系。我不知道如何构建外键约束,因为我觉得订单表应该包含order,而送货地址应该包含shipping_address_id,对吗?这让一切都变得更加混乱。

请帮我解决这个问题。

这是我的EERD:enter image description here

1 个答案:

答案 0 :(得分:0)

这是因为您当前的设计意味着多个user_order行可以引用相同的单shipping_address行。

您需要更改设计,以便多个user_order行无法引用相同的单shipping_address行。

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

  1. UNIQUE
  2. 上添加user_order.shipping_address_id约束
  3. 或者:反转关系(这是我的首选选项,因为它消除了不需要的代理键):
    1. 删除user_order.shipping_address_id列。
    2. shipping_address.id更改为shipping_address.order_id,以便它是[{1}}
    3. 的外键
    4. user_order.id的新主键设为shipping_address.order_id
  4. 请注意,这两个选项都是非规范化,因为它可以防止不同订单之间共享送货地址(例如,如果同一个客户重复订购相同的重复订单),尽管这可能是有意的 - 因此,如果用户&#39 ;未来的地址变更,无法追溯更新旧订单发货记录。

    其他一些提示:

    • 考虑使用shipping_address而不是int作为您的身份 - 我怀疑您在每张表中都有超过20亿行。
    • 不要盲目地对所有文本列使用bigint - 使用它来强制对数据长度进行合理约束,例如varchar(255)不需要长于2个字符如果您使用的是ZIP + 4,则可以state存储缩写{/ 1}}。
    • 不要在您的数据库中存储完整的信用卡号码(如您的zipcode表中所示) - 这违反了PCI规则,这是一个巨大的责任,可能是非法疏忽你的管辖权。您的支付处理商将为您提供替代不透明令牌值(或类似的东西)作为识别充值卡和将未来费用应用于存储的付款详细信息的方法 - 您可以合理存储的最多4位数。加密数据是否与数据无关。