我确定这是一个重复的问题,但我还没有找到合适的答案,所以我想我会问这个(我认为)非常常见的数据库设计问题:< / 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.
那么这里的正确方法是什么?
感谢。
答案 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对象继承,这样你就可以重用代码了不得不妥协你的数据模型。