假设有两种模式:User
和Question
。我可以使用@OneToMany
表示一个用户可以有多个问题。现在,如果我想允许用户关注一个或多个问题,我应该构建一个具有两个属性(用户和问题)的Follow
模型吗?或者只是将一个属性添加到User
模型中以获取所遵循的问题列表?哪一个更好?这种情况的一般设计原则是什么?考虑到后端数据库操作,上面哪种方法会更有效?
答案 0 :(得分:1)
这里的关键想法是,一个问题只有一个提问者,但有多个粉丝。在数据模型中工作,您可以将所有内容设想为表,您可以按如下方式进行设计:
USER (id(PK), name, ...)
QUESTION (id(PK), title, text, author(FK to USER))
FOLLOW (userid(FK to USER), questionid (FK to QUESTION))
因为作者关系是从USER到QUESTION的一对多,以及USER和QUESTION之间的多对多关系。 FOLLOW表是通常的连接表。
现在用JPA做ORM就是让事情变得有趣的地方。是的,您可以通过存储每个用户的问题列表来避免显式构建Follow
类。您需要@ManyToMany
和@JoinTable
。这比明确的Follow
类更有效,可能有两个@ManyToOne
s或两个@OneToMany
s?我不太确定,但我怀疑,因为JPA只是一个规范,并且可以有多个实现,也许不同的实现可能会有很好的性能。您当然可以尝试两种方式,编写一些查询,然后查看生成的SQL。如果您已经了解有效获取策略的技巧,并且具有避免n + 1选择问题等其他技能,那么您可能会发现这是一个有趣的练习。
当然,避免连接表的模型类更多是ORM-ish,因为您可以只关注对象级别而不必过多担心底层表。但是,了解幕后发生的事情是很好的,因为你仍然需要了解如何进行有效的提取以及如何避免n + 1选择等。
此外,如果您的关注关系具有自己的属性,您可能会发现明确的Follow
模型类是个好主意。
底线是一个多对多的直线,没有Follow
模型可能是最干净的,但选择最适合你的东西,如果你有任何疑问,可以进行一些分析。我相信最终只看生成的SQL会告诉你你想知道什么,因为JPA没有指定SQL。 JPA实现也可能非常聪明。