SQL 组字段建模架构
SQL schema for modelling of group fields
有人要求我对现有的 SQL 数据库进行一些调整,但是我无法确定如何为以下场景建模:
目前,订单商品可以或不能与托拍相关联。目前这只是数据库中的一个整数字段table。如果该订单项目的某些字段已更新,这需要反映在共享相同 PalletID 的所有其他项目中。我被要求通过代码进行这种同步,但感觉很糟糕,而且很容易不同步。
我考虑制作一个新的 table tblPallet,它将包含共享字段,但是如果订单商品没有托盘,订单商品仍需要存储自己的这些详细信息副本:
订单商品
ID,
描述,
托盘编号,
当前阶段,
位置,
托盘
ID,
当前阶段,
地点
有人对此建模有任何替代想法吗?
1) 如果一件或多件物品在放在托盘上之前可以共享相同的 CurrentStage
和 Location
我会使用以下解决方案(在这种情况下 CurrentStage
和 [=项目级别的 14=] 列和货盘级别的 CurrentStage
和 Location
是异或;如果 OrderItemGroup.CurrentStage
和 OrderItemGroup.Location
已填充,则 OrderItemGroup.PalletID
应该为 NULL 或者如果OrderItemGroup.PalletID
被填充然后 OrderItemGroup.CurrentStage
和 OrderItemGroup.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) 但是如果在放在托盘上之前,来自同一订单的物品(大多数时候)有不同的 CurrentStage
和 Location
我会使用以下解决方案(在这种情况下 [=项目级别的 13=] 和 Location
列以及货盘级别的 CurrentStage
和 Location
是异或):
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
有人要求我对现有的 SQL 数据库进行一些调整,但是我无法确定如何为以下场景建模:
目前,订单商品可以或不能与托拍相关联。目前这只是数据库中的一个整数字段table。如果该订单项目的某些字段已更新,这需要反映在共享相同 PalletID 的所有其他项目中。我被要求通过代码进行这种同步,但感觉很糟糕,而且很容易不同步。
我考虑制作一个新的 table tblPallet,它将包含共享字段,但是如果订单商品没有托盘,订单商品仍需要存储自己的这些详细信息副本:
订单商品
ID, 描述, 托盘编号, 当前阶段, 位置,
托盘
ID, 当前阶段, 地点
有人对此建模有任何替代想法吗?
1) 如果一件或多件物品在放在托盘上之前可以共享相同的 CurrentStage
和 Location
我会使用以下解决方案(在这种情况下 CurrentStage
和 [=项目级别的 14=] 列和货盘级别的 CurrentStage
和 Location
是异或;如果 OrderItemGroup.CurrentStage
和 OrderItemGroup.Location
已填充,则 OrderItemGroup.PalletID
应该为 NULL 或者如果OrderItemGroup.PalletID
被填充然后 OrderItemGroup.CurrentStage
和 OrderItemGroup.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) 但是如果在放在托盘上之前,来自同一订单的物品(大多数时候)有不同的 CurrentStage
和 Location
我会使用以下解决方案(在这种情况下 [=项目级别的 13=] 和 Location
列以及货盘级别的 CurrentStage
和 Location
是异或):
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