在任何Web应用程序中,我们都遇到了这样的场景:我们可以使用Table每个类层次结构 或每个子类的表。但重要的是要决定哪一个更适合您的用例。 我已经提出了基本的理解,哪一个更好?
Scenario :-
员工。永久和合同员工扩展了员工。
存在两种选择: -
Option 1:-
每个类层次结构的表,其中我们表示单个表中的所有字段。
关于它的好处,你可以从单个表中获取所有细节,并摆脱Employee和Permanent / Contract Employee之间的连接。
所以提高了性能。但是,即使在您认为不可能的字段上,也无法声明非空约束
永久雇员为null(因为我们在单表中为永久雇员和合同雇员提供服务)。这是缺点。
Option 2:-
每个子类的表,我们有父表的外键引用。加入这里会降低性能。
但是,是的,你可以在第一个选项中使用无法做出的约束,而不是在第一个选项中无法做到。
My take :-
如果您不需要设置约束,请继续使用选项1,因为摆脱加入对性能pov有利。
想听听是否有更多的方面或我的理解是否正确?
答案 0 :(得分:4)
请注意未来读者:自该答案发布以来,该问题已经过严格修改。第二点可能不再有意义了
您的问题有两个答案:
这些概念与一对一或多对一关联无关,它们与您在类设计中处理继承的方式相关,并在数据库设计中进行转换。在某个时刻,您简要地谈到了长期雇员和合同雇员。所以你的困境肯定是:
我的课程
PermanentEmployee
和ContractEmployee
扩展了课程Employee
。我是否需要为两种类型的员工(每个层次结构的表)使用一个表,还是需要ContractEmployee
的表和PermanentEmployee
的另一个表(每个子类的表)?
有了这个困境,是的,非零约束的存在具有重要性。使用第一个策略,您将得到一个包含所有常用列的表,所有列都是特定于承包商的,所有列都是特定于永久物的,还有一个用于歧视的附加列(例如,它将包含承包商的“CON”和“PER”对于永久物)。如果存储永久物,则将为承包商特定的列设置所有列为null。因此,您无法强制执行诸如“承包商具有强制性end_contract_date列”之类的规则,因为将对于永久物来说为空。
支持或反对的其他参数是性能:第一个策略使用更多空格,有大量空列,而在第二个策略中,您复制两个表中的公共列,如果您想要选择所有员工(无论如何)承包商/永久)你将不得不建立一个SELECT UNION。
一对一和多对一与您的表和联接相关。如果您具有一对一,则表示您有两个具有受限外键的表(唯一)。如果你有多对一,同样的东西,但fk并不是唯一的。
对于您的多对一示例,您是正确的,规范化需要您的两个表。对于您的一对一,您也应该使用两个表,但您可以使用EmployeeDetails的组件,然后只有一个表。请参阅this hibernate documentation,它将解释它(请注意,从词汇的角度来看,它不再是一对一的)。