Разработка базы данных для изображений - PullRequest
3 голосов
/ 01 июля 2010

Я хотел бы получить ваш совет относительно дизайна базы данных. У меня есть 4 различных элемента данных (таблицы A, B, C, D), например: A - Содержание B - Категории C - Авторы а также D - Изображения

Каждая запись в таблицах A, B, C могла бы ассоциировать 1 или несколько разных изображений в таблице D, НО для каждого изображения в D должна быть однозначно связана только запись в A, B, C. Это означает, что изображения не могут быть разделены (между другими таблицами).

Моя идея состояла в том, чтобы создать разные таблицы изображений для каждого элемента данных, используя тип связи ONE to MANY. Пример: Содержание -> Изображение-Содержание а также Категории -> Категории изображений

Вопросы? Мой дизайн базы данных хороший?

Поскольку таблицы «Содержимое изображения» и «Категории изображения» могут иметь аналогичные свойства, такие как «URL-адрес файла» или «Название-изображения», я подумал, может ли существовать наиболее подходящее решение для проектирования базы данных. *

Спасибо за ваше время

Ответы [ 4 ]

2 голосов
/ 01 июля 2010

Пожалуй, наиболее распространенный способ реализации этого проекта - упомянутая выше схема «одна таблица на тип владельца» (таблицы для изображений, «Владелец 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

(Технически, это хороший пример варианта исключительной "проблемы" моделирования данных типа / подтипа.)

1 голос
/ 05 июля 2010

Да, вы смотрите в правильном направлении.

Сохраните текущую настройку четырех таблиц, а затем создайте еще 3, которые содержат только метаданные, которые сообщают вам о связи между, например, таблицей содержимогои таблицы изображений.

Например, таблица изображений с содержимым будет иметь столбцы: id, идентификатор содержимого, идентификатор изображения

и т. д.

1 голос
/ 05 июля 2010
create table A (IDA int not null, primary key(IDA));
create table B (IDB int not null, primary key(IDB));
create table C (IDC int not null, primary key(IDC));

create table Image(IDI int, A int null, B int null, C int null, Contents image,
foreign key (A) references A(IDA),
foreign key (B) references B(IDB),
foreign key (C) references C(IDC),
check (
(A is not null and B is null and C is null) or
(A is null and B is not null and C is null) or
(A is null and B is null and C is not null)
));
1 голос
/ 01 июля 2010

Я думаю, вы хотели бы таблицу, которая отображает каждый из ABC на изображение. Например:

Content   -> ContentImages -> Images
---------    -------------    ------
ContentId    ImageId          ImageId
             ContentId

Categories -> CategoryImages   -> Images
----------    ----------------    ------
CategoryId    ImageId             ImageId
              CategoryId

Authors    -> AuthorImages     -> Images
----------    ----------------    ------
AuthorId      ImageId             ImageId
              AuthorId

Это может показаться немного громоздким, но я думаю, что это нормальная форма .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...