我有以下物品管理要求。
以下是数据库设计:
item_master
-----------
- ItemId
- Item name
- etc...
item_location_history
------------------
- ItemId
- LocationId (foreign key of location_master)
- Date
在运输物品时,我想以下列方式插入数据:
1.在运输时我想在特定日期输入要从“A”位置移动到“In Transit”的项目。因为物品有可能在“运输中”状态保持数天
2.在收到位置'B'时,我想在特定日期插入要从'In Transit'移动到位置'B'的项目,依此类推。
这样我就可以跟踪“In Transit”状态和项目位置。
实现这一目标的最佳方法是什么?我需要对上述架构进行哪些更改?感谢。
答案 0 :(得分:0)
您可以将in_transit的布尔字段添加到item_location_history,这样当它从位置A移动到位置B时,您将LocationId设置为位置B(因此您知道它的去向)但是当它实际到达时您将记录另一行,其中LocationId为LocationB,但in_transit为false。这样你知道什么时候到了。
如果您在“运输途中”不需要知道它的位置,那么您只需添加“In Transit”作为位置并保持架构相同即可。在过去的库存应用中,我尽量让每辆卡车都成为一个位置,以便我们知道该物品所属的特定卡车。
答案 1 :(得分:0)
我多年来采用的一种技术是从实体表中规范化过渡属性(数量,状态,位置等)。如果您还想跟踪历史记录,只需要版本(versionize?)后续状态表。
create table ItemLocation(
ItemID int,
Effective date,
LocationID int,
Remarks varchar( 256 ),
constraint PK_ItemLocation primary key( ItemID, Effective ),
constraint FK_ItemLocation_Item foreign key( ItemID )
references Items( ID ),
constraint FK_ItemLocation_Location foreign key( LocationID )
references Locations( ID )
);
有几个很好的设计方案,我已经展示了最简单的,其中暗示了“在途中”。请考虑以下数据:
ItemID Effective LocationID Remarks
====== ========= ========== ===============================
1001 2015-04-01 15 In location 15
1001 2015-04-02 NULL In Transit [to location xx]
1001 2015-04-05 17 In location 17
当项目1001到达位置15时,它出现在数据库中,在那里它花费一整天。第二天它被移除并运送。三天后,它到达第17位,直到今天仍然存在。
隐含的含义通常是不受欢迎的,并且确实很容易过度。如果需要,您可以添加实际状态字段以包含“In location”和“In Transit”值。如果您认为以后可能会添加其他状态值(QA测试,接收,保持等),您可能会考虑这样的课程。但是对于两个可能的值,In Location或In Transit,暗示意义有效。
无论如何,您通过使用最新生效日期获取LocationID来了解任何项目的当前行踪。您还可以记录项目在任何日期的位置 - 两者都可以使用相同的查询。
declare AsOf date = sysdate;
select i.*, il.Effective, IfNull( l.LocationName, 'In Transit' ) as Location
from Items i
join ItemLocation il
on il.ItemID = i.ID
and il.Effective =(
select Max( Effective )
from ItemLocation
where ItemID = il.ItemID
and Effective <= AsOf )
left join Locations l
on l.ID = il.LocationID;
将AsOf值设置为“今天”以获取最新位置,或将其设置为任意日期以查看该日期的位置。由于当前位置将是最常见的查询,因此请定义仅生成当前位置并在连接中使用该位置的视图。
join CurrentItemLocation cil
on cil.ItemID = i.ID
left join Locations l
on l.ID = cil.LocationID;