Страницы

Поиск по вопросам

вторник, 28 мая 2019 г.

Как проверить “составной” объект на уникальность?

Стоит задача организовать создание и хранение уникальных сборок инструментов. Под сборкой инструмента подразумевается набор уникальных инструментов(фрезы, сверла и т.п.).
Структуру бд я представляю как то так:
Справочник Инструментов; Справочник Сборок; Таблица для связи двух вышеуказанных справочников(многие ко многим: ToolId & AssemblyId)
Сборка считается уникальной на основании инструментов в неё входящих, т.е. не должно быть несколько сборок состоящих из одинаковых позиций.
Например, сборка №1 состоит из следующих позиций, Патрон №1, Фреза №5. Необходимо запретить создание сборок состоящих только из Патрон №1 и Фреза №5 при наличии существующей сборки, но можно создать сборку №2 состоящую из Патрон №1, Фреза №5, Удлинитель №2
Можно ли как то это сделать на стороне бд?


Ответ

Сборки можно хранить в виде дерева, где у каждой сборки будет указан последний инструмент и ссылка на сборку без этого инструмента:
Сборка1 = Сборка2 + Инструмент
Если нет двух одинаковых пар (Сборка, Инструмент) в БД - то все сборки будут уникальными.
create table assemblies ( id bigint identity(0,1) primary key, tool bigint not null foreign key references tools(id), parent bigint null foreign key references assemblies(id),
unique (parent, tool) )
Но тут есть проблема - данное представление будет считать сборки "Инструмент1 + Инструмент2" и "Инструмент2 + Инструмент1" различными. Для того, чтобы проверялась уникальность без учета порядка - надо принудительно упорядочить инструменты внутри сборки по номеру.
Для того, чтобы не пропустить неверно упорядоченные сборки - скопируем поле tool родительской сборки в дочернюю, проверив корректность при помощи составного внешнего ключа:
create table assemblies ( id bigint identity(0,1) primary key, tool bigint not null foreign key references tools(id),
parent bigint null, parenttool bigint null,
-- Две строки ниже нужны чтобы нельзя было установить некорректное значение parenttool foreign key (parent, parenttool) references assemblies(id, tool), check (parent is null and parenttool is null or parent is not null and parenttool is not null),
-- Собственно, проверка уникальности сборок check (tool > parenttool or parenttool is null), unique (parent, tool) )

Комментариев нет:

Отправить комментарий