SQL 组字段建模架构

SQL schema for modelling of group fields

有人要求我对现有的 SQL 数据库进行一些调整,但是我无法确定如何为以下场景建模:

目前,订单商品可以或不能与托拍相关联。目前这只是数据库中的一个整数字段table。如果该订单项目的某些字段已更新,这需要反映在共享相同 PalletID 的所有其他项目中。我被要求通过代码进行这种同步,但感觉很糟糕,而且很容易不同步。

我考虑制作一个新的 table tblPallet,它将包含共享字段,但是如果订单商品没有托盘,订单商品仍需要存储自己的这些详细信息副本:

订单商品

ID, 描述, 托盘编号, 当前阶段, 位置,

托盘

ID, 当前阶段, 地点

有人对此建模有任何替代想法吗?

1) 如果一件或多件物品在放在托盘上之前可以共享相同的 CurrentStageLocation 我会使用以下解决方案(在这种情况下 CurrentStage 和 [=项目级别的 14=] 列和货盘级别的 CurrentStageLocation 是异或;如果 OrderItemGroup.CurrentStageOrderItemGroup.Location 已填充,则 OrderItemGroup.PalletID 应该为 NULL 或者如果OrderItemGroup.PalletID 被填充然后 OrderItemGroup.CurrentStageOrderItemGroup.Location 应该是 NULL):

OrderItem(
    ID - PK, 
    OrderID - FK, 
    ... other columns except PalletID, CurrentStage, Location ...
)

OrderItemGroup(
    ID - PK, 
    OrderItemID - FK, 
    CurrentStage - allows NULLs, 
    Location - allows NULLs, 
    PalletID - FK - it allows NULLs, 
    CHECK(CurrentStage IS NOT NULL AND Location IS NOT NULL AND PalletID IS NULL 
    OR CurrentStage IS NULL AND Location IS NULL AND PalletID IS NOT NULL)
    -- {CurrentStage, Location} xor {PalletID}
)

Pallet(
    ID - PK, 
    CurrentStage - NOT NULL, 
    Location - NOT NULL
)

2) 但是如果在放在托盘上之前,来自同一订单的物品(大多数时候)有不同的 CurrentStageLocation 我会使用以下解决方案(在这种情况下 [=项目级别的 13=] 和 Location 列以及货盘级别的 CurrentStageLocation 是异或):

OrderItem(
    ID - PK, 
    OrderID - FK, 
    CurrentStage - allows NULLs, 
    Location - allows NULLs, 
    PalletID - FK - it allows NULLs, 
    CHECK(CurrentStage IS NOT NULL AND Location IS NOT NULL AND PalletID IS NULL 
    OR CurrentStage IS NULL AND Location IS NULL AND PalletID IS NOT NULL)
    -- {CurrentStage, Location} xor {PalletID}
)

Pallet(
    ID - PK, 
    CurrentStage - NOT NULL, 
    Location - NOT NULL
)

2.1) 如果您必须存储位置历史记录,那么我会使用以下方法(这不是唯一的解决方案,但在我看来是最简单的):

OrderItem(
    ID - PK, 
    OrderID - FK, 
    -- other columns except CurrentStage, Location and PalletID
)

Pallet(
    ID - PK, 
    CurrentStage - NOT NULL, 
    Location - NOT NULL
)

OrderItemLocationHistory (
    ID - PK,
    OrderItemID - FK,
    IsCurrentLocation BIT NOT NULL DEFAULT (1),
    CurrentStage - allows NULLs, 
    Location - allows NULLs, 
    PalletID - FK - it allows NULLs, 
    CHECK(CurrentStage IS NOT NULL AND Location IS NOT NULL AND PalletID IS NULL 
    OR CurrentStage IS NULL AND Location IS NULL AND PalletID IS NOT NULL)
    -- {CurrentStage, Location} xor {PalletID}
)

    -- SQL2008+ following unique filtered index guarantee there is only only one row with IsCurrentLocation = 1 for every OrderItemID
    SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON
    SET NUMERIC_ROUNDABORT OFF
    GO
    /*
    See section [Required SET Options for Filtered Indexes]:
https://msdn.microsoft.com/en-us/library/ms189292.aspx
    */
    CREATE UNIQUE INDEX IXF_OrderItemLocationHistory_OrderItemID_IsCurrentLocation1
    ON dbo.OrderItemLocationHistory (OrderItemID)
    WHERE IsCurrentLocation = 1