假设我们有三个概念如下:
概念(attribute1,attribute2,..)
A(a,b,c,d)
B(a,b,c,d,e)
C(a,b,c,d,f)
在数据库中为这三个概念建模有三种选择:
1)按原样建模
表{column1,column2,...}
A {id,a,b,c,d}
B {id,a,b,c,d,e}
C {id,a,b,c,d,f}
Con: 有数据冗余。
2)在一个表中建模
A {id,object_type,a,b,c,d,e,f}
Con: 对于某些概念,某些字段仍为空。
3)使用表格之间的关系
A {parent_id,a,b,c,d}
B {id,parent_id,e}
C {id,parent_id,f}
Con: 提高连接表的查询复杂性。
您会使用哪种方法?你有其他解决方案吗?你认为第三种方法的性能较差吗?
答案 0 :(得分:5)
显然,你的选择1是最糟糕的选择。这里的主要问题是您需要复制B
中C
和A
的所有行,从而造成严重的维护问题。
您的选项2称为 单表继承 模式,建议在子表没有(m)任何其他列的情况下使用。
您的选项3称为 连接表继承 模式,其中子表(表示子类)通过其主键连接到它们的超级表,也是引用超级表的外键
因此,对于您的抽象示例,似乎选项2是推荐的方法,因为您的表B
和C
只有一个附加列。
请注意,根据连接表继承方法,无需添加主键属性(就像您在id
和{{1}中对B
所做的那样}})。您只需使用与supertable相同的原始键,并使其成为引用超级表的外键。因此,在这种方法中,模式将是
C
您可以在我的教程Subtyping and Inheritance with Database Tables部分中了解有关使用类层次结构开发前端Web应用程序的更多信息。
答案 1 :(得分:1)
Propel开发人员说,从SQL和查询性能的角度来看,选项2"是最有效的实现,但仅限于少量的继承字段" http://propelorm.org/Propel/documentation/09-inheritance.html