2013-08-04 58 views
0

我正在設計一個快遞數據庫。如何處理字段的數據結構隨時間變化?

在一個parcel表中,我需要一個字段來告訴我一些關於包裹的當前狀態和位置的信息。

如果包裹已經達到了快遞公司的分支目標,本場必須指向關於送貨人信息等

如果包裹至今仍然在快遞公司的分支機構旅行,此字段必須指向關於攜帶包裹的車輛的信息等。

我該如何處理這種異質性?

回答

1

是否有無數的狀態,或者可以將它分解爲離散列表?

如果答案是後者 - 由於「快遞公司的分支機構」部分屬於您的問題,我認爲這是真實的,所以您可以創建一個具有id號碼的交叉參考卡車的查找表。簡單的加入(http://www.w3schools.com/sql/sql_join.asp)應該返回您正在查找的信息。

+0

我明白引用,但需要根據時間點引用2個不同的表。有時它會是送貨員,有時候會是卡車。 – batman

+0

送貨人的信息與卡車有很大不同。 – batman

+0

*「有無限數量的狀態,還是可以將其分解爲離散列表?」* @learner:這是更重要的問題。 –

0

您可以通過引用包裹表中的兩個不同的表格來實現此目的,其中一個表示信使的分支,另一個表示目的地的信息。如果一個不適用於包裹,那麼它將是空的。如果你不想打破正常形式,你可以在狀態表中獲得這些信息,然後加入到這些其他表中,如果沒有信息從你知道冷靜,你知道狀態不適用於包裹。

0

列「other_columns」是可能適用於表的所有其他列的佔位符。包裹只有兩種處置:(t)ransit,或(d)elivered。

create table parcel_dispositions (
    parcel_id integer not null, 
    disposition_timestamp timestamp (0) not null 
     default current_timestamp, 
    parcel_disposition char(1) not null 
     default 't' 
     check (parcel_disposition in ('t', 'd')), 
    other_columns char(1) default 'x', 
    primary key (parcel_id, disposition_timestamp, parcel_disposition) 
); 

create table parcels_in_transit (
    parcel_id integer not null, 
    disposition_timestamp timestamp not null, 
    parcel_disposition char(1) not null 
     default 't' 
     check (parcel_disposition = 't'), 
    other_columns char(1) not null default 'x', 
    primary key (parcel_id, disposition_timestamp, parcel_disposition), 
    foreign key (parcel_id, disposition_timestamp, parcel_disposition) 
     references parcel_dispositions (parcel_id, disposition_timestamp, parcel_disposition) 
); 

create table parcels_delivered (
    parcel_id integer not null, 
    disposition_timestamp timestamp not null, 
    parcel_disposition char(1) not null 
     default 'd' 
     check (parcel_disposition = 'd'), 
    other_columns char(1) not null default 'x', 
    primary key (parcel_id, disposition_timestamp, parcel_disposition), 
    foreign key (parcel_id, disposition_timestamp, parcel_disposition) 
     references parcel_dispositions (parcel_id, disposition_timestamp, parcel_disposition) 
); 

insert into parcel_dispositions values 
(1, '2013-01-01 09:35', 't', 'x'), 
(1, '2013-01-03 17:33', 't', 'y'), 
(1, '2013-01-08 08:00', 'd', 'z'); 


insert into parcels_in_transit values 
(1, '2013-01-01 09:35', 't', 'a'), 
(1, '2013-01-03 17:33', 't', 'b'); 

insert into parcels_delivered values 
(1, '2013-01-08 08:00', 'd', 'c'); 

在生產中,您通常會拒絕對基表的訪問,並基於類似的東西構建可更新的視圖。 (一個視圖用於傳遞包裹,另一個視圖用於傳遞包裹。)應用程序代碼使用視圖,而不是基礎表。

create view all_parcels_in_transit as 
select t1.* 
from parcel_dispositions t1 
inner join parcels_in_transit t2 
     on t1.parcel_id = t2.parcel_id 
     and t1.disposition_timestamp = t2.disposition_timestamp 
     and t1.parcel_disposition = t2.parcel_disposition; 

SQL dbms尚未執行某些合理的約束條件。例如,交付後,數據庫不應該接受給定宗地的更多處置,但SQL dbms不能強制執行。 (不能以聲明方式強制執行,但可以使用觸發器強制執行)