我正在考虑Hibernate管理的类层次结构的表布局,当然每个子类的表技术在一般意义上都是最合适的。但是,通过逻辑思考,我对它的性能有一些担忧,特别是随着子类数量的增加。Hibernate的每个子类的继承策略的效率
举一个非常简短的(和经典)例如,假设您有以下类:
public abstract class Animal {
int pkey;
String name;
}
public class Dog extends Animal {
long numSlippersChewed; // int is not large enough...
}
public class Cat extends Animal {
short miceCaught; // ... but here int is far bigger than required :-)
}
(我eliding getter和setter和Hibernate映射等等,仅仅假设他们是基本明显的情况)。
这些实体的数据库表是有意义的,你会得到很好的非规范化等等。但是,Hibernate为了取出个体动物而做了什么查询呢?我能想到的至少两种情况下,这可能会发生:
- 有一个对一个(或一个一对多)映射,如
Human
类的pet
领域的一些其他实体。这将存储pkey,所以当Hibernate获取一个Human对象时,它也需要获取相应的Animal
对象。当给定动物的pkey时,Hibernate会使用什么查询来提取和解组实际动物数据,因为它可能位于Cat
或Dog
表中? - HQL如
from Animal where name='Rex'
(让我们假设名称是唯一的)。这与上述类似,因为它可以让您在超类表中标识一行,但您不知道要检查哪个子类表以获取更多详细信息。 HQL是否甚至允许您发出查询from
抽象类? (尽管使用子类特定的东西很好,例如from Cat where miceCaught > 5
)。
我可以想到两种方式,这可以在SQL中完成,而且看起来都不漂亮。一种是针对给定的pkey在每个子类表上运行exists
查询,然后从返回命中的表中加载。或者,Hibernate可以在所有表中执行一些可怕的联合查询 - 实质上是模拟每个层次表的方案,因为结果集将包含所有可能子类的属性,并且子类表中的各个选择返回null
作为无关参数。后一种情况可能甚至需要添加一个合成鉴别器列,以便Hibernate可以知道哪个子类表实际返回了该行,从而知道应该分析哪些Java类。
事情变得多毛太多,如果你有具体的类型的亚型:
public class Greyhound extends Dog {
float lifetimeRacingWinnings;
}
现在对于一个给定的动物p键,有可能是在Dog
和Greyhound
表有效行,这意味着我的第一种手动检查与pkey相对应的类的方法变得更加困难。
我非常担心的原因是我会希望在类层次结构上使用这种方法,最多有70个类,最大嵌套链的级别为4-5,因此对所有这些进行联合查询是可能会有可怕的表现。 Hibernate有没有什么小窍门可以保持这种相对高性能?或者正在通过pkey加载对这些类中的一个的引用需要很长时间?
也许你想看到http://stackoverflow.com/questions/2700680/table-per-subclass-inheritance-relationship-how-to-query-against-the-parent-clas – 2010-06-18 01:49:40
出于好奇我不知道是否其他一些基于JPA对象的存储系统也有同样的问题(即ObjectDB)。换句话说,也许标准的关系数据库可能不是最好的技术,特别是因为你有一个巨大的对象图。 – 2010-12-25 15:36:38