我已经完成了一个项目,该项目实质上是一个在线书店,可以在其中购买书籍并下订单。
我的数据库包含各种表,例如: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图时,它给了我两种不同的关系。 order
和收货地址之间为1:1关系,而从收货地址到订单为1:M关系。我不知道如何构造外键约束,因为我认为订单表应包含shipping_address_id
,送货地址应包含order_id
,对吗?这只是让一切变得更加混乱。
请帮助我。
这是我的EERD:
最佳答案
发生这种情况是因为您当前的设计意味着多个user_order
行可以引用同一单个shipping_address
行。
您需要更改设计,以使多个user_order
行无法引用同一单个shipping_address
行。
至少有两种可能的解决方案:
在UNIQUE
上添加user_order.shipping_address_id
约束
或者:反转关系(这是我的首选,因为它消除了不需要的代理键):
删除user_order.shipping_address_id
列。
将shipping_address.id
更改为shipping_address.order_id
,使其成为user_order.id
的外键
将shipping_address.order_id
设置为shipping_address
的新主键。
请注意,这两个选项都是非规范化的,因为它可以防止在不同订单之间共享送货地址(例如,如果同一位客户多次下达相同的重复订单),尽管这样做可能是有意的-这样,如果用户的未来地址发生变化,则可能会赢不会无意地追溯更新旧订单的运输记录。
其他一些技巧:
考虑使用int
而不是bigint
进行身份验证-我怀疑每个表中是否有超过20亿行。
不要盲目地对所有文本列使用varchar(255)
-使用它来对数据长度施加合理的约束,例如,如果要存储缩写,则state
不必超过2个字符,同上zipcode
如果您使用的是ZIP + 4,则可以为varchar(10)
。
不要在数据库中存储完整的信用卡号! (如您的payment
表中所示)-这违反了PCI规则,在您的管辖范围内承担巨额责任,并且可能是非法过失。您的付款处理器将为您提供一个替代的不透明令牌值(或类似的值),作为识别签帐卡并将未来的费用应用于已存储的付款明细的一种方法-您可以合理地存储的最多是最后4位数字。加密数据与否无关紧要。
关于mysql - ER图中的基数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44641383/