SQL Server 2008数据库中字段的复杂约束

时间:2011-04-22 09:30:36

标签: sql-server-2008 unique-constraint

我有以下(简化)结构,允许我跟踪已分配给单元格的设备。由于设备只能在表格中的单元格中,我创建了一个约束,表明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约束关系)

我是否需要从代码,事务,不同的模型中强制执行这些关系?

也许有一种我不知道的设计模式可以帮助存储这些历史数据?

1 个答案:

答案 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和工作单,并查看工作单表中的日期。