关系数据库设计:条件
Relational Database Design: Conditionals
我正在设计一个关系数据库,我打算用 SQL 来实现。我有一个正在处理的用例,但似乎在思考解决方案时遇到了一些麻烦。该设计用于电子商务订单系统。
用例:
ORDER_DETAILS
table 包含一个 deliveryMethod
属性。然后我有一个包含地址信息的 SHIPPING_DETAILS
table 和一个包含亲自取件的位置、日期和时间信息的 PICKUP_DETAILS
table。当用户下订单时,他们可以选择将订单运送到他们的地址或亲自取货。我目前的想法是在ORDER_DETAILS
table中有一个shippingId
外键和pickupId
外键。然后,基本上 运行 对 deliveryMethod
属性进行条件检查,并根据该属性的值("shipping" 或 "pickup" 从适当的 table 检索数据).但是,有了这个想法,我将允许 shippingId
或 pickupId
属性的 ORDER_DETAILS
中存在空值。据我了解,空值在关系设计中被视为负面。所以我正在寻找有关此设计的一些反馈。这个可以吗?我是否过度考虑了空值?有没有更有效的方法来设计这个特定的模式?
如果我理解正确你的问题,
- ORDER 与 SHIPPING 关系的基数为 1 ---> (0, 1)
- ORDER与PICKUP关系的基数为1 ---> (0, 1)
- 订单必须有送货或取件,但不能同时有。
要强制执行约束 (#3),您可以在数据库中定义功能约束。这进入了有趣的东西。
无论如何,就像您说的,您可以在 ORDER 中创建作为 SHIPPING 或 PICKUP table 的 FK 的列,但它们都可以为空。我不认为 null FK 是邪恶的或任何东西,但它们确实会变得混乱,尤其是当你有一大堆交付方法而不仅仅是两种时。
如果您不喜欢空值,您可以有单独的关联 table:(1) ORDER_DELIVERY 只有一个 order_id 和一个 delivery_id ,每个都是各自 table 的 FK,和 (2) ORDER_PICKUP,也是两列 table。在每种情况下,主键都是 order_id
。现在没有空值:送货订单在 ORDER_DELIVERY table 中,取货订单在 ORDER_PICKUP.
中
当然有一个权衡,因为保持只有一种且只有一种交付方法的约束不是跨 table 秒的一致性检查。
另一个想法是将送货和取货详细信息设置为 JSON 字段。在这里,您在应用程序方面做了更多工作,以编程方式强制执行约束,但不会有空值。
我希望我可以说这里有一个灌篮高手的设计模式,但我没有看到。就个人而言,只有两种类型的交付方式,我不会回避空值(因为我不是纯粹主义者)。但是当数据库完成工作时我确实喜欢它,所以....
(呵呵,问题"are you over thinking things?"的答案是否定的,这个思路真好!)
我正在设计一个关系数据库,我打算用 SQL 来实现。我有一个正在处理的用例,但似乎在思考解决方案时遇到了一些麻烦。该设计用于电子商务订单系统。
用例:
ORDER_DETAILS
table 包含一个 deliveryMethod
属性。然后我有一个包含地址信息的 SHIPPING_DETAILS
table 和一个包含亲自取件的位置、日期和时间信息的 PICKUP_DETAILS
table。当用户下订单时,他们可以选择将订单运送到他们的地址或亲自取货。我目前的想法是在ORDER_DETAILS
table中有一个shippingId
外键和pickupId
外键。然后,基本上 运行 对 deliveryMethod
属性进行条件检查,并根据该属性的值("shipping" 或 "pickup" 从适当的 table 检索数据).但是,有了这个想法,我将允许 shippingId
或 pickupId
属性的 ORDER_DETAILS
中存在空值。据我了解,空值在关系设计中被视为负面。所以我正在寻找有关此设计的一些反馈。这个可以吗?我是否过度考虑了空值?有没有更有效的方法来设计这个特定的模式?
如果我理解正确你的问题,
- ORDER 与 SHIPPING 关系的基数为 1 ---> (0, 1)
- ORDER与PICKUP关系的基数为1 ---> (0, 1)
- 订单必须有送货或取件,但不能同时有。
要强制执行约束 (#3),您可以在数据库中定义功能约束。这进入了有趣的东西。
无论如何,就像您说的,您可以在 ORDER 中创建作为 SHIPPING 或 PICKUP table 的 FK 的列,但它们都可以为空。我不认为 null FK 是邪恶的或任何东西,但它们确实会变得混乱,尤其是当你有一大堆交付方法而不仅仅是两种时。
如果您不喜欢空值,您可以有单独的关联 table:(1) ORDER_DELIVERY 只有一个 order_id 和一个 delivery_id ,每个都是各自 table 的 FK,和 (2) ORDER_PICKUP,也是两列 table。在每种情况下,主键都是 order_id
。现在没有空值:送货订单在 ORDER_DELIVERY table 中,取货订单在 ORDER_PICKUP.
当然有一个权衡,因为保持只有一种且只有一种交付方法的约束不是跨 table 秒的一致性检查。
另一个想法是将送货和取货详细信息设置为 JSON 字段。在这里,您在应用程序方面做了更多工作,以编程方式强制执行约束,但不会有空值。
我希望我可以说这里有一个灌篮高手的设计模式,但我没有看到。就个人而言,只有两种类型的交付方式,我不会回避空值(因为我不是纯粹主义者)。但是当数据库完成工作时我确实喜欢它,所以....
(呵呵,问题"are you over thinking things?"的答案是否定的,这个思路真好!)