通用资源表设计方法

时间:2014-09-10 04:57:05

标签: sql sql-server database database-design

我确定这是一个重复的问题,但我还没有找到合适的答案,所以我想我会问这个(我认为)非常常见的数据库设计问题:< / p>

我正在设计一个SQL数据库,它将包含不同的包含图像的记录类型,因此表A和B都包含不同的记录类型,它们的每一行都链接到多个图像记录。

我正在尝试决定是否采用创建1个通用表的方法来存放所有图像(让我们称之为#34;图像&#34;)或是否创建两个不同的表(&#34) ; AImage&#34;和#34; BImage&#34;)分别存放每种记录类型的图像。

A及其图像与B及其图像之间存在一对多的关系

如果我创建通用Image表,它将具有列:Id,ParentType(在本例中为A或B),ParentId。和ImagePath。这种方法看起来更清晰(特别是因为表&#34; AImage&#34;和#34; BImage&#34;彼此相同),但我几乎立即遇到问题(比如在尝试建立外键约束时)。我应该注意到,数据库中可能还有其他记录类型需要具有相同的一对多关系的图像,如表A和表A所示。 B.

那么这里的正确方法是什么?

感谢。

2 个答案:

答案 0 :(得分:1)

这是经典的Polymorphic Association反模式。有许多可能的解决方案:

1)专属弧,例如对于图像表

Id  Image_Path       TableA_Id TableB_Id
1   /path/to/image1  1
2   /path/to/image2            1
3   /path/to/image3  2

TableA_Id和TableB_Id都可以为空,并且一个必须不为空。可以在TableA_Id和TableB_Id上声明外键。

2)反转关系,例如从Images表中删除Parent_Type和Parent_Id并创建两个新表

TableA_Images

Image_Id  TableA_Id
1         1
3         2

TableB_Images

Image_Id  TableB_Id
2         1

可以在TableA_Id和TableB_Id上声明外键。

3)为TableA / TableB创建一个超类型表,例如TableSuper,并让Images表引用这个新表的主键。

您需要根据具体情况决定哪种方法最合适。

答案 1 :(得分:1)

您应该创建两个单独的图像表,一个用于与对象类型A相关的(多个)图像,另一个用于与对象类型B相关的(多个)图像。还有其他方法可以执行此操作,但它们不是通常是一个好主意。

仅仅因为两个表具有相似的列并不意味着这些表实际上是相同的表。

正如您所知,A_IMAGE和B_IMAGE在一个非常重要的方面已经不同了,它们有不同的外键列和约束。

以这种方式保持看起来相似的表格对于程序员来说似乎有问题,因为它感觉不像是好的代码重用。但是,构建代码以获得最佳实践可维护性(例如OO)的规则不同于构建数据以获得最佳实践可维护性的规则(例如,正常形式)。

如果它让你感觉不像需要10个淋浴:当你为A_IMAGE和B_IMAGE表创建CRUD代码时,让aImageCrud和bImageCrud对象都从公共的imageCrud对象继承,这样你就可以重用代码了不得不妥协你的数据模型。