Пожалуй, наиболее распространенный способ реализации этого проекта - упомянутая выше схема «одна таблица на тип владельца» (таблицы для изображений, «Владелец A», «Изображения владельца A») и повтор для владельцев B, C и т. Д. ). Другим распространенным способом реализации этого является одна «центральная» таблица для изображений с идентификатором одного владельца, хранящимся в этой таблице. Ваши критерии особенно ограничивают то, что изображение может быть связано с одним и только одним владельцем, но существует несколько типов владельцев. Внедрить такие ограничения внутри базы данных сложно, но реализовать их вне базы данных гораздо сложнее и проблематичнее по всем обычным причинам (приложение, выполняющее работу с базами данных, и что происходит, когда кто-то изменяет базу данных вне выделенного приложения?)
Ниже приведен пример того, как эти структуры и ограничения могут быть реализованы в базе данных. Он может показаться суетливым, подробным и чрезмерно сложным, но он справится со своей задачей, и после правильной реализации вам никогда не придется беспокоиться о том, были ли ваши данные непротиворечивыми и действительными.
Во-первых, все изображения хранятся в следующей таблице. Должно быть известно, какому «типу» владельца может быть назначено изображение; установите это в ImageType, и (согласно ограничениям в более поздних таблицах) изображение не может быть назначено любому другому типу владельца. Когда-либо. (Вы также можете установить ограничение CHECK для ImageType, чтобы гарантировать, что в таблицу можно загружать только допустимые типы изображений.)
CREATE TABLE Image
(
ImageId int not null
,ImageType char(1) not null
,constraint PK_Image
primary key clustered (ImageId, ImageType)
)
Затем создайте несколько таблиц владельцев. Вы можете иметь любое их количество, я просто делаю два для примера.
CREATE TABLE A
(
AId int not null
constraint PK_A
primary key clustered
)
CREATE TABLE B
(
BId int not null
constraint PK_B
primary key clustered
)
Создайте таблицы связей, отметив комментарии рядом с определениями ограничений. (Это слишком суетливая часть ...)
CREATE TABLE Image_A
(
ImageId int not null
constraint PK_Image_A
primary key clustered -- An image can only be assigned to one owner
,AId int not null
,ImageType char(1) not null
constraint DF_Image_A
default 'A'
constraint CK_Image_A__ImageType
check (ImageType in ('A')) -- Always have this set to the type of the owner for this table
,constraint FK_Image_A__A
foreign key (AId) references A (AId) -- Owner must exist
,constraint FK_Image_A__Image
foreign key (ImageId, ImageType) references Image (ImageId, ImageType) -- Image must exist *for this type of owner*
)
-- Same comments for this table
CREATE TABLE Image_B
(
ImageId int not null
constraint PK_Image_B
primary key clustered
,BId int not null
,ImageType char(1) not null
constraint DF_Image_B
default 'B'
constraint CK_Image_B__ImageType
check (ImageType in ('B'))
,constraint FK_Image_B__B
foreign key (BId) references B (BId)
,constraint FK_Image_B__Image
foreign key (ImageId, ImageType) references Image (ImageId, ImageType)
)
Загрузить некоторые образцы данных
ВСТАВИТЬ Значения изображения (1, 'A')
INSERT Image values (2, 'A')
INSERT Image values (3, 'B')
INSERT Image values (4, 'B')
INSERT A values (101)
INSERT A values (102)
INSERT B values (201)
INSERT B values (102)
Просмотр текущего содержимого таблиц:
SELECT * from A
SELECT * from B
SELECT * from Image
SELECT * from Image_A
SELECT * from Image_B
И сделать несколько тестов:
-- Proper fit
INSERT Image_A (ImageId, AId) values (1, 101)
-- Run it again, can only assign once
-- Cannot assign the same image to a second owner of the proper type
INSERT Image_A (ImageId, AId) values (1, 102)
-- Can't assign image to an invalid owner type
INSERT Image_B (ImageId, BId) values (1, 201)
-- Owner can be assigned multiple images
INSERT Image_A (ImageId, AId) values (2, 101)
(Это отбрасывает таблицы тестирования)
drop table Image
drop table A
drop table B
drop table Image_A
drop table Image_B
(Технически, это хороший пример варианта исключительной "проблемы" моделирования данных типа / подтипа.)