Java JPA是处理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

我一直在尝试使用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 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
}
  • 映射复杂性,当与其他类型的关系(如(B)
  • 在编写了简单的SQL查询之后,我觉得在这种动态模型中,列不是字段,而是属性,会更容易一些。有什么建议吗


    我正在使用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"}]