我有以下(简化)结构,允许我跟踪已分配给单元格的设备。由于设备只能在表格中的单元格中,我创建了一个约束,表明idEquipment和idCell在表格中必须是唯一的。
CREATE TABLE [dbo].[CellEquipment](
[idEquipment] [int] NOT NULL,
[idCell] [int] NULL,
CONSTRAINT [PK_CellEquipment] UNIQUE NONCLUSTERED
(
[idEquipment] ASC,
[idCell] ASC
)
此约束确保我永远不会将同一件设备添加到单元格两次。
所以现在我的任务是保存历史信息。我需要能够提取工单,查看其日期,然后找到该工单上使用的设备。解决方案是将日期信息添加到表中,如下所示:
CREATE TABLE [dbo].[CellEquipment](
[idEquipment] [int] NOT NULL,
[idCell] [int] NULL,
[DateAdded] [datetime] NULL,
[DateRemoved] [datetime] NULL,
)
现在我的约束被打破了。 idCell/idEquipment
不再是唯一的,因为设备可以被移除并重新添加到单元格中。现在我有一些棘手的日期问题需要解决。为确保数据完整性,对数据库的更改必须满足以下条件:
idCell/idEquipment are unique (like before) OR
idCell/idEquipment's new DateAdded doesn't fall between a DateAdded/Removed OR
idCell/idEquipment's new DateRemoved doesn't fall between a DateAdd/Removed or
idCell/idEquipment's doesn't have a record with DateRemoved=NULL
Check约束无法将其关闭,并且唯一索引约束也无法执行此操作。 BTW可以创建Check Constraint以确保DateAdded < DateRemoved
(以及其他NULL / NOT NULL约束关系)
我是否需要从代码,事务,不同的模型中强制执行这些关系?
也许有一种我不知道的设计模式可以帮助存储这些历史数据?
答案 0 :(得分:1)
由于我不知道 equipment 和 cell 对你来说意味着什么,所以我可能会离开这里。
但在我看来,重要的信息是在“工单号码中使用了什么设备?”的问题。日期并没有真正给你这些信息。但是这个(航空代码)结构可能会。
create table work_order_equpiment (
idEquipment integer not null,
idCell integer not null,
foreign key (idEquipment, idCell) references CellEquipment (idEquipment, idCell),
work_order_number integer not null references workorders (work_order_number),
primary key (idEquipment, idCell, work_order_number)
);
这使得在给定的工单上使用设备变得非常简单。要获取在给定日期使用的设备,请加入CellEquipment,work_order_equipment和工作单,并查看工作单表中的日期。