Java JPA是处理EAV数据模型的错误选择吗?
我一直在尝试使用JPA/Hibernate来CRUD操作EAV数据模型,并且一直面临着很多性能问题。我正在寻找有效管理EAV数据模型的想法Java JPA是处理EAV数据模型的错误选择吗?,java,spring,hibernate,jpa,spring-data-jpa,Java,Spring,Hibernate,Jpa,Spring Data Jpa,我一直在尝试使用JPA/Hibernate来CRUD操作EAV数据模型,并且一直面临着很多性能问题。我正在寻找有效管理EAV数据模型的想法 **(A)**So here is an example of what I am trying to deal with, I have three tables : UserTable AttributesTable UserAttributeValueTable **(B)**And apart from these three, I have ot
**(A)**So here is an example of what I am trying to deal with, I have three tables :
UserTable
AttributesTable
UserAttributeValueTable
**(B)**And apart from these three, I have other relations like :
ItemTable
UserItemsRelationTable
所以基本上,AttributesTable是一个包含所有属性的表,可以是用户的属性,也可以是项目的属性。UserAttributeValueTable是连接UserId、AttributeId和值的表
现在,假设我想提取所有用户及其属性
下面是我如何映射它们的:
@Entity
UserTable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="USER_ID")
private long userId;
@OneToMany(targetEntity=UserAttributeValueTable.class, mappedBy="userTable", fetch=FetchType.LAZY)
private List<UserAttributeValueTable> userAttributeValues;
//Other Columns
}
@Entity
UserAttributeValueTable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="USER_ATTRIBUTE_VALUE_ID")
private long userAttributeValueId;
@Column(name="\"VALUE\"")
private String value;
//bi-directional many-to-one association to AttributesTable
@ManyToOne(targetEntity=AttributesTable .class ,fetch=FetchType.LAZY)
@JoinColumn(name="ATTRIBUTE_ID")
private AttributesTable attributes;
//bi-directional many-to-one association to UserTable
@ManyToOne(targetEntity=UserTable.class,fetch=FetchType.LAZY)
@JoinColumn(name="USER_ID")
@JsonIgnore
private UserTable user;
//Other columns
}
@Entity
AttributeTable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="ATTRIBUTE_ID")
private long attrId;
@Column(name="ATTRIBUTE_NAME")
private String attrName;
//Other columns
}
我正在使用Spring Data JPA。我最近开发了一个应用程序,其中的数据结构类似。所采取的方法是在平坦的DB数据顶部创建DB视图。这些视图为我们提供了一个更相关的数据视图,并且只包含我们感兴趣的字段。JPA实体映射到这些视图。在我们的例子中,这些数据是只读的:如果不是这样,就不确定这种方法是否有效。从JPA查询生成的原始SQL的性能如何?对于EAV模型,SQL性能通常是一个问题。如果您确实需要坚持使用EAV,那么首先通过减少联接并对其排序以及引入索引来优化原始SQL。如果即使这样也不能在您期望的范围内获得性能,您将需要探索一个平面表结构,如Magento。对于JPA来说,这当然不容易。@AlanHay,这就是问题所在,我们也需要插入,它不仅仅是只读的。我考虑过视图选项,但当插入图片时,我放弃了。感谢您的输入:)@manish我们确实需要坚持EAV。问题在于JPA并不是运行带有内部联接的单个查询,而是运行多个查询来检索每个属性的值。仅当它基于主键时,它才运行内部联接查询。编写sql查询比让他们使用JPA更容易。我们还在研究。我不知道Magento是如何做到的,但是感谢您的输入,我将尝试使用索引来优化查询。您可以在JPA中始终使用原始SQL。只需在代码中生成SQL并通过JPA提供程序运行即可。也就是说,如果您确信原始SQL的性能良好。任何ORM的一般规则是,在奇怪的情况下,您无法通过查询获得正确的性能级别,请切换到普通JDBC和原始SQL。
User :[{ id:"1", name:"John", otherAttributes={attr1:"value1",attr2:"value2"},{ id:"2", name:"Joey", otherAttributes={attr1:"value1",attr2:"value2"}]