2010-07-01 76 views
3

我希望得到您关于数据库设计的建议。 我有4个不同的数据元素(表A,B,C,d)实施例: A - 内容 乙 - 分类 Ç - 作者 和 d - 图片图像数据库设计

在表A,B,C中的每个记录可能在表D中有一个或多个不同的图像, 但是对于D中的每个图像必须唯一地与A,B,C中的记录相关联。 这意味着图像不能共享(在其他表之间)。

我的想法是为每个数据元素创建不同的图像表,使用ONE to MANY关联类型。 实施例: 内容 - >图像-内容 和 类别 - >图像类别

问题? 我的数据库设计是一个很好的?由于表格“图像内容”和“图像类别”可能具有类似的属性,如“文件 - 网址”或“图像标题”,我关心的是如果可能存在一个最合适的数据库设计解决方案。

感谢您的时间

+1

您可以创建一个带有诸如File-Url等字段的Images表。然后,Image-Contents表将与Images表中的一行具有一对一的关系。 – Pace 2010-07-01 13:47:44

+0

只是要清楚。设计可能是: 目录 - >图像内容 - >图像 类别 - >图像 - 类别 - >图像 作者 - >图像作者 - >图像 模式是: 一对一-many - >链接表 - >一对一 正确吗? – GibboK 2010-07-01 14:03:54

+0

这之前已经问过:http://stackoverflow.com/questions/3150557/separate-link-association-tables-for-different-data就我个人而言,我喜欢OO超类型方法。 – BenV 2010-07-06 16:55:10

回答

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

也许实现这种设计最常见的方式是用你提到的“每个所有者类型一个表”方案(表格图像,“所有者A”,“所有者A图像”,并且为所有者B,C,等等)。另一种常见的实现方式是使用一个“中心”表格来存储图片,单个所有者的ID存储在该表格中。您的标准尤其受到限制,因为图像可能与一个且只有一个所有者相关联,但拥有多种类型的所有者。在数据库中实现这样的约束是非常棘手的,但是在数据库之外实现这些约束要困难得多,并且出现所有常见原因(数据库的应用程序工作,以及有人在专用应用程序之外修改数据库时会发生什么?)

以下是如何在数据库中实现这些结构和约束的示例。它可能看起来很挑剔,细节和过于复杂,但它会完成这项工作,一旦正确实施,您就不必担心数据是否一致和有效。

首先,所有图像都存储在下表中。必须知道图像可能分配给哪个所有者的“类型”;在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 
) 

构建关联表,注意约束定义旁边的注释。 (这是过于繁琐部分...)

​​

负载一些示例数据

插入图像值(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 

(Techincally,这是在独特的类型/子类型的数据建模 “问题” 的变体的一个很好的例子。)

+0

这是一个认真长的答案...很难甚至验证 - 但看起来正确:) – Randy 2010-07-05 13:06:31

+0

几个月前我听说过这个策略,现在看来这是一个很好的尝试。为了便于使用,您可以在Image_X表格的顶部放置分区视图,但是我已经把它放在了一边,因为它已经够混乱了。 – 2010-07-05 14:15:30

+0

感谢您的设计,我需要尝试它,我尽快回复你。 – GibboK 2010-07-05 14:24:27

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,图像ID

等。