繁体   English   中英

图像数据库设计

[英]Data Base Design for Images

我想了解有关数据库设计的建议。 我有4个不同的数据元素(表A,B,C,D)示例:A - 内容B - 类别C - 作者和D - 图像

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

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

有问题吗? 我的数据库设计很好吗?

由于表“图像内容”和“图像类别”可能具有类似“File-Url”或“Image-Title”的属性,因此我担心是否存在最合适的数据库设计解决方案。

谢谢你的时间

也许最常见的实现此设计的方法是使用您提到的“每个所有者类型一个表”方案(图像表,“所有者A”,“所有者A图像”,以及所有者B,C等的重复)。 实现此目的的另一种常见方法是使用一个“中央”表格,其中单个所有者的Id存储在该表中。 您的标准特别有限,因为图像可能只与一个所有者相关联,但有多种类型的所有者。 在数据库中实现这样的约束是很棘手的,但是在数据库之外实现它们要困难得多,并且出于所有常见原因(应用程序执行数据库工作,以及当有人在专用应用程序之外修改数据库时会发生什么?)会出现问题。

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

首先,所有图像都存储在下表中。 必须知道可以为图像分配所有者的“类型”; 在ImageType中设置它,并且(根据后面表格中的约束)不能将图像分配给任何其他类型的所有者。 永远。 (您还可以在ImageType上放置一个CHECK约束,以确保只能在表中加载有效的图像类型。)

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)
 )

加载一些样本数据

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

(从技术上讲,这是独占类型/子类型数据建模“问题”的变体的一个很好的例子。)

我想你会想要一张将每个ABC映射到图像的表格。 例如:

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

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

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

这看起来有点麻烦,但我认为这是正常的形式

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)
));

是的,你正朝着正确的方向前进。

保留四个表的当前设置,然后创建另外三个表,只保存元数据,告诉您例如内容表和图像表之间的链接。

例如,images-content表将包含列:id,content-id,image-id

等等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM