如何处理字段的数据结构随时间变化?

时间:2013-08-04 16:04:18

标签: database database-design

我正在设计一个快递数据库。

在一个parcel表中,我需要一个字段来告诉我一些关于包裹的当前状态和位置的信息。

如果包裹已到达快递公司的目的地分支,则该字段必须指向有关送货人的信息等。

如果包裹仍然穿过快递公司的分支机构,则该字段必须指向有关运送包裹的车辆的信息等。

我如何处理这种异质性?

3 个答案:

答案 0 :(得分:1)

是否存在无限数量的状态,还是可以将其分解为离散列表?

如果答案是后者 - 我认为这是正确的,因为“快递公司的分支”是您问题的一部分,您可以创建一个查找表,交叉引用带有ID号的卡车。一个简单的连接(http://www.w3schools.com/sql/sql_join.asp)应该返回您正在寻找的信息。

答案 1 :(得分:0)

您可以通过引用宗地表中的两个不同的表来执行此操作,一个表示快递的分支,另一个表示目的地的信息。如果一个不适用于包裹,那么它将为空。如果你不想破坏普通表格,你可以在状态表中将这些信息加入到这些其他表中,如果没有信息冷却,你知道状态不适用于地块。

答案 2 :(得分: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尚未执行某些明智的约束。例如,在交付之后,数据库不应再接受给定parcel的任何更多处置,但SQL dbms还不能强制执行。 (不能以声明方式强制执行。但是你可以使用触发器强制执行它。)