Hibernate适合的继承策略
Hibernate suitable inheritance strategy
这是parentclass
@MappedSuperclass
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class APostCommon extends Actionable {
private static final long serialVersionUID = 1L;
@Column(name = "TITLE")
private String title;
@Lob
@Column(name="DESCRIPTION")
private String description;
//omitted others for purity
}
这是一个childclass
@Entity
@Table(name="QUESTION")
public class Question extends APostCommon {
private static final long serialVersionUID = 1L;
@Transient
private List<Answer> answers;
@Column(name="FOLLOW_COUNT")
private Integer followerCount;
@Column(name="ANSWER_COUNT")
private Integer answerCount;
//omitted others for purity
}
Answer
与超级class 的唯一区别在于包含 questionId
字段
@Entity
@Table(name="ANSWER")
public class Answer extends APostCommon{
private String questionId;
//omitted others for purity
}
哪种数据模型适合我。我应该使用 InheritanceType.SINGLE_TABLE
还是 TABLE_PER_CLASS
。当未来有数百万条记录时会发生什么。
在我准备 JPA 证书时,这些是我对这两种策略的精心挑选的笔记:
单一Table策略
该方法可能更浪费数据库 table 空间,但它确实为多态查询和写入操作提供了最佳性能。
发出这些操作所需的SQL简单、优化且不需要加入
- 你的优点:也许你的设计不会很好和规范化,但你会在性能方面省去很多麻烦,而且你的查询也会简单得多特别是如果您希望有数百万条问题和答案记录。
- 你的缺点:我猜问题和答案会有很多共同点,而且,随着时间的推移和 table 的增长,许多不同的属性/列。您最终可能会得到那些臃肿的 tables 之一,它们包含所有可能的数据和平,并且在某些时候无法维护(不是一次我必须得到整个部门的批准和几天的测试才能将单个索引添加到像这样的 table 的列之一)。
加入策略
为每个实体映射 table 提供规范化数据模式提供的数据重用,并且是存储数据的最有效方式,由层次结构中的多个子类共享。
- 你的优点: 随着时间的推移,问题和答案之间的额外不同列的数量 tables 不是问题,因为你的架构很好并且规范化,因此每个都有一个合乎逻辑的位置。设计干净、清晰、可维护和可扩展(可能您可能需要为专门的问题和答案添加更多抽象)。
- 你的缺点:
有数百万行的问题和答案,你至少需要一个额外的连接来进行基本查询,但如果你随着列/特性的增长保持标准化,最小连接数将高于此。
结论:
最初我倾向于单身 Table,但当我给自己一点时间时,它意识到这将是一个 'lazy' 决定(把所有东西都放在一个袋子里然后忘记design).Joined Tables 似乎是一个更成熟的决定,因为你需要考虑你的索引策略,你应该规范化多少 tables(以及哪些数据组)并最终提出高效查询,批处理语句。
决定权在你,但如果你选择联合策略,你肯定会增加你的技能组合,因为它会要求更高。
这是parentclass
@MappedSuperclass
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class APostCommon extends Actionable {
private static final long serialVersionUID = 1L;
@Column(name = "TITLE")
private String title;
@Lob
@Column(name="DESCRIPTION")
private String description;
//omitted others for purity
}
这是一个childclass
@Entity
@Table(name="QUESTION")
public class Question extends APostCommon {
private static final long serialVersionUID = 1L;
@Transient
private List<Answer> answers;
@Column(name="FOLLOW_COUNT")
private Integer followerCount;
@Column(name="ANSWER_COUNT")
private Integer answerCount;
//omitted others for purity
}
Answer
与超级class 的唯一区别在于包含 questionId
字段
@Entity
@Table(name="ANSWER")
public class Answer extends APostCommon{
private String questionId;
//omitted others for purity
}
哪种数据模型适合我。我应该使用 InheritanceType.SINGLE_TABLE
还是 TABLE_PER_CLASS
。当未来有数百万条记录时会发生什么。
在我准备 JPA 证书时,这些是我对这两种策略的精心挑选的笔记:
单一Table策略
该方法可能更浪费数据库 table 空间,但它确实为多态查询和写入操作提供了最佳性能。
发出这些操作所需的SQL简单、优化且不需要加入
- 你的优点:也许你的设计不会很好和规范化,但你会在性能方面省去很多麻烦,而且你的查询也会简单得多特别是如果您希望有数百万条问题和答案记录。
- 你的缺点:我猜问题和答案会有很多共同点,而且,随着时间的推移和 table 的增长,许多不同的属性/列。您最终可能会得到那些臃肿的 tables 之一,它们包含所有可能的数据和平,并且在某些时候无法维护(不是一次我必须得到整个部门的批准和几天的测试才能将单个索引添加到像这样的 table 的列之一)。
加入策略
为每个实体映射 table 提供规范化数据模式提供的数据重用,并且是存储数据的最有效方式,由层次结构中的多个子类共享。
- 你的优点: 随着时间的推移,问题和答案之间的额外不同列的数量 tables 不是问题,因为你的架构很好并且规范化,因此每个都有一个合乎逻辑的位置。设计干净、清晰、可维护和可扩展(可能您可能需要为专门的问题和答案添加更多抽象)。
- 你的缺点: 有数百万行的问题和答案,你至少需要一个额外的连接来进行基本查询,但如果你随着列/特性的增长保持标准化,最小连接数将高于此。
结论:
最初我倾向于单身 Table,但当我给自己一点时间时,它意识到这将是一个 'lazy' 决定(把所有东西都放在一个袋子里然后忘记design).Joined Tables 似乎是一个更成熟的决定,因为你需要考虑你的索引策略,你应该规范化多少 tables(以及哪些数据组)并最终提出高效查询,批处理语句。
决定权在你,但如果你选择联合策略,你肯定会增加你的技能组合,因为它会要求更高。