Сложные ограничения на поля в базе данных SQL Server 2008 - PullRequest
1 голос
/ 22 апреля 2011

У меня есть следующая (упрощенная) структура, которая позволяет мне отслеживать оборудование, которое было назначено ячейке. Поскольку оборудование может находиться в ячейке только один раз в таблице, я создал ограничение, в котором говорится, что 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 не имеют возможности справиться с этим, и ограничения уникального индекса также не могут этого сделать. Между прочим, можно создать проверочное ограничение, чтобы гарантировать, что DateAdded < DateRemoved (вместе с другими отношениями ограничения NULL / NOT NULL)

Нужно ли принудительно применять эти отношения из кода, транзакции, другой модели?

Возможно, существует шаблон проектирования, о котором я не знаю, который может помочь с хранением таких исторических данных?

1 Ответ

1 голос
/ 22 апреля 2011

Так как я не знаю, что для вас значат оборудование и клетка , я могу быть далеко от базы.

Но мне кажется, чтоВажная информация в вопросе "Какое оборудование использовалось в номере рабочего задания?"Даты не дают вам такой информации.Но эта (воздушный код) структура могла бы.

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.

...