例如,我有2个表:'customer'和'staff'。它们几乎相同,只有2个属性不同。那么我应该创建另一个名为'person'的表包含'customer'和'staff'的所有相同属性,然后创建fk键指向这个'person'?类似于类设计中的继承。
这种方法有什么缺点吗?
答案 0 :(得分:6)
是的,这种方法有一个缺点。联接增加了查询的复杂性(在某些情况下非常如此),如果你不小心,可能会增加查询时间。
相反,执行此操作的标准方法(即,当子类之间只有少数属性不同时模拟对象继承)是执行名为Single Table Inheritance的操作。此方法以一些未使用的数据库空间为代价来防止数据库连接。
它的工作原理如下:您创建一个包含所有属性的表,包括仅适用于其中一个属性的属性,以及用于指定对象类型的type
属性。例如,如果customer
具有属性:
id
,name
,email
,password
,order_date
AND staff
有属性:
id
,name
,email
,password
,hire_date
然后,您创建一个包含所有属性列的表和一个类型:
id
,type
,name
,email
,password
,order_date
,hire_date
type
列将始终包含“customer”或“staff”。如果type
是“customer”,则hire_date
始终为NULL,并且无意义。如果type
是“staff”,则order_date
始终为NULL,并且没有意义。
答案 1 :(得分:5)
您正在描述模式调用Class Table Inheritance。这是一个有效的设计,但与任何其他设计一样,它必须具有良好的判断力。阅读Martin Fowler的“企业应用程序架构模式”,了解其优缺点的更多细节。
有些人警告不要使用连接,但只有在需要特定于子类的列时才需要连接。当给定查询只需要公共列时,您可以避免额外的连接。
答案 2 :(得分:4)
Pranay Rana和Ben Lee都是正确的,最终的答案是:“这取决于”。
您必须权衡子类特定列的数量与公共列的数量,以确定适合您的方式。单表继承不能很好地扩展:当你必须引入第三种类型的子类时会发生什么?例如供应商?
就此而言,您如何对待也是客户的员工?
答案 3 :(得分:3)
查找“泛化专业化关系建模”。你会找到一些关于这个主题的好文章。大多数示例遵循与Bill提供给您的Class Table Inheritance链接相同的模式。
还有一个细节。专业表(对于您的客户和员工)不会自动编写他们的id fieid。相反,当您填充它们时,id字段应该获得通用表中的id字段的副本(在您的情况下为person)。
这使得专业ID可以完成双重任务。它们都是对genralized表中相应行的pk和fk引用。这使得连接更容易,更快。
创建具有与通用表连接的每个专用表的视图会很方便。或者,您可以创建一个大视图,该视图生成您在另一个响应建议的单个表继承模式中看到的相同数据。它基本上是一堆连接的联合。
答案 4 :(得分:2)
嗯,我说它的设计很好,因为你没有重复数据,那就是数据规范化了。
只有一件事就是你正常化你的加入会增加。