我正在设计一个快递数据库。
在一个parcel
表中,我需要一个字段来告诉我一些关于包裹的当前状态和位置的信息。
如果包裹已到达快递公司的目的地分支,则该字段必须指向有关送货人的信息等。
如果包裹仍然穿过快递公司的分支机构,则该字段必须指向有关运送包裹的车辆的信息等。
我如何处理这种异质性?
答案 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还不能强制执行。 (不能以声明方式强制执行。但是你可以使用触发器强制执行它。)