Database 图像数据库设计

Database 图像数据库设计,database,database-design,Database,Database Design,我想听听你关于数据库设计的建议。 我有4个不同的数据元素(表A、B、C、D)示例: A-目录 B类 C-作者 和 D-图像 表A、B、C中的每个记录都可以在表D中关联1个或多个不同的图像, 但对于D中的每个图像,必须仅与a、B、C中的一个记录唯一关联。 这意味着图像不能(在其他表之间)共享 我的想法是为每个数据元素创建不同的图像表,使用一对多关联类型。 例子: 内容-->图像内容 和 类别-->图像类别 有问题吗? 我的数据库设计好吗 由于表“图像内容”和“图像类别”可能具有类似于“文件Url”

我想听听你关于数据库设计的建议。 我有4个不同的数据元素(表A、B、C、D)示例: A-目录 B类 C-作者 和 D-图像

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

我的想法是为每个数据元素创建不同的图像表,使用一对多关联类型。 例子: 内容-->图像内容 和 类别-->图像类别

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

由于表“图像内容”和“图像类别”可能具有类似于“文件Url”或“图像标题”的属性,我担心是否存在最合适的数据库设计解决方案


感谢您抽出时间

我想您需要一个表,将每个ABC映射到一个图像。例如:

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



这似乎有点麻烦,但我认为这是最常见的。

也许实现此设计的最常用方法是使用您提到的“每种所有者类型一个表”方案(图像表,“所有者a”、“所有者a图像”,并重复所有者B、C等)。实现这一点的另一种常见方法是使用一个用于图像的“中心”表,并在该表中存储单个所有者的Id。您的条件特别有限,因为图像可能与一个且仅一个所有者关联,但有多种类型的所有者。在数据库内部实现这些约束是很棘手的,但由于所有常见的原因(数据库工作的应用程序,以及当有人在专用应用程序之外修改数据库时会发生什么情况),在数据库外部实现这些约束要困难得多,问题也大得多

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

首先,所有图像都存储在下表中。必须知道可以将图像分配给什么“类型”的所有者;在ImageType中设置,并且(根据后面表格中的约束)图像不能分配给任何其他类型的所有者。曾经(您还可以对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’)

查看表的当前内容:

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)
(这将删除测试表)


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

是的,您的方向是正确的

保留四个表的当前设置,然后再创建三个仅包含元数据的表,这些元数据告诉您内容表和图像表之间的链接

例如,图像内容表将包含以下列:id、content id、image id


等等。

您可以创建一个包含文件Url等字段的图像表。然后图像内容表将与图像表中的一行建立一对一的关系。请澄清。设计可以是:内容-->图像内容-->图像类别-->图像类别-->图像作者-->图像作者-->图像模式是:一对多-->链接表-->一对一正确吗?以前有人问过这一点:我个人喜欢OO超类型方法。这是一个非常长的答案。。。甚至很难验证——但看起来是正确的:)几个月前我就听说过这个策略,现在似乎是尝试的好时机。为了便于使用,您可以将分区视图放在Image_X表的顶部,但我忽略了这一点,因为它已经够乱了。感谢各位的设计,我需要尝试一下,然后尽快返回给您。谢谢Philip,我测试了您的脚本,工作正常。我现在唯一关心的是性能,你认为如果我保留我的第一个设计,quesry会更快吗?我的想法是为每个数据元素创建不同的图像表,使用一对多关联类型。示例:内容-->图像内容和类别-->图像类别性能完全取决于您执行的查询类型。有了适当的索引,检索一行应该很快;如果索引不好,最终会对所有内容运行表扫描。我把我认为是“默认/明显”的索引放在表上;如果“Image_X.XId”列足够大,那么这些列上的额外索引应该会有所帮助。这里最好的建议是用兆字节的数据填充dev表,对它们运行例行查询,然后从那里开始工作。
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 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
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)
));