如何将项目显示为“传输中”而不是特定位置ID(外键)?

时间:2015-04-27 06:13:42

标签: mysql database database-design relational-database

我有以下物品管理要求。

  1. 项目可以从“A”位置移动到“B”。之后它也可以从'B'移动到'C'位置。
  2. 应为每个项目保留历史记录,以便在特定时间段内显示位置明智的项目,可以显示项目明智的历史记录。
  3. 此外,我需要在特定日期显示“在途中”的物品。
  4. 以下是数据库设计:

    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”状态和项目位置。

    实现这一目标的最佳方法是什么?我需要对上述架构进行哪些更改?感谢。

2 个答案:

答案 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;