2010-07-01 5 views
3

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

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

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

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

Поскольку таблицы «Image-Contents» и «Image-Categories» могут иметь сходное свойство, например «File-Url» или «Image-Title», я имел в виду, если бы существовало наиболее подходящее решение для проектирования баз данных.

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

+1

Вы можете создать таблицу изображений с такими полями, как File-Url и т. Д. Затем таблица Image-Contents будет иметь отношение «один к одному» с строкой в ​​таблице «Изображения». – Pace

+0

Просто, чтобы быть ясным. Дизайн может быть: Содержание -> Image-Содержание -> Изображения Категории -> Image-Категории -> Изображения Авторы -> Image-Авторы -> Изображения Схема является: один-к -many -> Таблица ссылок -> один к одному Правильно? – GibboK

+0

Это было задано до: http://stackoverflow.com/questions/3150557/separate-link-association-tables-for-different-data Лично мне нравится подход супертипа OO. – BenV

ответ

1

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

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

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

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

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

2

Возможно, наиболее распространенным способом реализации этого проекта является описанная вами схема «одна таблица на тип владельца» (таблицы для изображений, «владелец», «владельцы изображений» и повторение для владельцев B, C, и т.д). Другим распространенным способом реализации этого является одна «центральная» таблица для изображений с идентификатором одного владельца, хранящимся в этой таблице. Ваши критерии особенно ограничены тем, что изображение может быть связано с одним и только одним владельцем, но есть несколько типов владельцев. Реализация таких ограничений внутри базы данных сложна, но внедрение их за пределами базы данных намного сложнее и проблематично по всем обычным причинам (приложение, работающее с базами данных, и что происходит, когда кто-то изменяет базу данных за пределами выделенного приложения?)

Ниже приведен пример того, как эти структуры и ограничения могут быть реализованы в базе данных. Это может показаться суетливым, подробным и чрезмерно сложным, но он выполнит эту работу, и после правильной реализации вам никогда не придется беспокоиться, были ли ваши данные согласованными и действительными.

Прежде всего, все изображения хранятся в следующей таблице. Должно быть известно, какой «тип» владельца может быть присвоен образ; установите в ImageType и (в соответствии с ограничениями в последующих таблицах) изображение не может быть присвоено любому другому владельцу. Когда-либо. (Вы также можете поместить СНЕСК на 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 

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

+0

Это серьезный длинный ответ ... трудно даже проверить - но выглядит правильно :) – Randy

+0

Я слышал об этой стратегии несколько месяцев назад, и это было подходящее время, чтобы попробовать. Для удобства использования вы можете удалить секционированный вид поверх таблиц Image_X, но я оставил его, поскольку он уже был довольно грязным. –

+0

Спасибо, ребята за ваш дизайн, мне нужно попробовать, и я возвращаюсь к вам как можно скорее. – GibboK

1
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

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

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

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

И так далее.

Смежные вопросы