【问题标题】:Complex Constraints on fields in SQL Server 2008 databaseSQL Server 2008 数据库中字段的复杂约束
【发布时间】:2011-04-22 09:30:35
【问题描述】:

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

检查约束没有能力解决这个问题,唯一索引约束也不能做到这一点。顺便说一句,可以创建一个检查约束以确保 DateAdded < DateRemoved(以及其他 NULL/NOT NULL 约束关系)

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

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

【问题讨论】:

  • 你说,“这个约束确保我永远不会将同一件设备添加到一个单元格中两次。”但它允许您将相同的设备添加到多个单元。这是你的意图吗?
  • 不幸的是,有些情况是允许的。例如,有一个烤箱(一个非常大的烤箱)为多个电池提供服务。由于烤箱已“校准”,因此需要对其进行跟踪。
  • 我不会说这很不幸。我只想说这就是业务的运作方式。

标签: sql-server-2008 unique-constraint


【解决方案1】:

由于我不知道 equipmentcell 对你来说意味着什么,所以我在这里可能有点离谱。

但在我看来,重要信息在于“工单编号中使用了什么设备?”这个问题。日期并没有真正给你这些信息。但是这种(航空代码)结构可能会。

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 和 workorders,并查看 workorders 表中的日期。

【讨论】:

  • 我认为这会增加数据库的冗余性,尽管您可能看不到我所说的内容。我们目前记录生产中的每个相关步骤,谁(员工),什么(工作订单),如何(工作步骤),何时(时间戳),何处(工作单元)。如果单元格/设备表可以知道日期,我可以通过在每件设备上仅添加 2 个日期来找到数据。如果我按照您的建议进行操作,我将获得数万或数十万个新条目(许多步骤 * 许多机器)。
  • 您的建议确实具有仅跟踪工作单元的当前状态的好处。我提出的解决方案跟踪工作单元的完整历史,这不是必需的(并且可能不会)。
  • "如果单元格/设备表可以识别日期,我只需在每台设备上添加 2 个日期即可找到数据。"我不这么认为。我认为您需要为每个工单添加一行,包括这两个日期。而且我看不到数据库有任何明显的方式来说明 this 设备用于that 工单。它只能说这件件设备是在那个日期使用的。在大多数情况下不是一回事,但在你的情况下可能是一样的。
  • 我有一个带有 WO/日期列的表。我有第二个表,其中包含单元格/日期/设备列。我可以加入这两个并说出WO通过时牢房里有什么设备。假设数据是推断出来的,但是在每个工作订单上的每件设备都使用 line tech 条码不会飞行将导致数千笔交易。综上所述,我在 OQ 中的重点是保持数据完整性,而您现在让我考虑结构化解决方案。
  • 结构是你的朋友。 (有时,它是你的唯一朋友。)
猜你喜欢
  • 2011-08-28
  • 2022-11-17
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多