我想知道hibernate在数据库设计方面的最佳实践。
我有一个用户实体,它将有很多不同的设置。对于每一组设置,我必须将它们作为额外列添加到用户表中,或者创建一个单独的实体并将它们与@onetoone关系连接起来。我的理解是,@onetomany和@manytoone关系通常应该在单独的表中发生,因为不应该有可选的列。
但对于“一元关系”来说,这还不太清楚。我认为使用@onetoone是有原因的,因为orms默认情况下会选择所有单个属性,并且有很多列会减慢这个过程。
我所说的一个例子可以用

@Entity
public class User{

@OneToOne
private ForumSettings forumSettings;

@OneToOne
private AccountSettings accountSettings;

@OneToOne
private SecuritySettings securitySettings;

}


@Entity
public class User{

@Column
private boolean showNSFWContent; //Forum Setting

@Column
private int numberOfCommentsPerPage; //Forum Setting

@Column
private boolean subscribedToNewsLetter; //Account Setting

@Column
private boolean isAccountBanned; //Account Setting

@Column
private boolean isTwoFactorAuthenticationEnabled; //Security Setting

@Column
private boolean alertForSuspiciousLogin; //Security Setting

}

上面是一个简单的例子来说明这个概念,但实际上在第二部分中会有更多的列。
我知道这可能是基于观点的,但我希望有人能分享两种选择的利弊。
非常感谢你

最佳答案

您的问题通常是关于数据规范化。规范化本身是一个广泛的研究领域,基本上是一种构造数据库表的方法,避免冗余,并确保更新不会引入异常。
标准化的第一条规则是,表中不应包含重复组。对你来说是的。
解决方案1:将用户设置作为实体存储为映射作为一个家庭关系

    @Entity
    public class User

    @OneToMany
    private List<UserSettings> userSettings;

然后您可以通过连接settingUser实体来查询特定的UserSettings类型。
例如(jpql)
  SELECT user u
  JOIN u.settings us
  WHERE us.settings_type = 'account_settings'
        and us.settings_value = 'secure' // or any other logic

这种方法的优点是UserSettings将拥有自己的持久性标识,并且可以由自己的持久性标识查询。它不依赖于父母。
例如:
 SELECT q from Query q where ...

解决方案2:在基本元素集合中存储设置
可以在集合中存储用户设置(每个用户都有自己的设置集)
   @Entity
        public class User {

            @Id
            @GeneratedValue(strategy=GenerationType.IDENTITY)
            private long id;

            private String name;

            ...

            @ElementCollection
            @CollectionTable(name="USER_SETTINGS")
            @MapKeyColumn(name="SETTINGS_TYPE")
            @Column(name="SETTINGS_VALUE")
            Map<String, Boolean> userSettings = new HashMap<>();

UserSettings集合将存储在一个单独的表中,其中包含foreign keyUser表。UserSettings没有自己的持久性id,依赖于User实体,只能通过它是父级('user')来查询。
解决方案3:将用户设置存储为嵌入类型
嵌入类型不是实体,它没有自己的持久性ID,依赖于父类型,作为父记录的一部分存储在数据库中(在User表中)
@Entity
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    private String name;

    ...

    @Embedded
    private UserSettings userSettings;

usersettings位于单独的类中,但存储在User表中。
@Embeddable
public class UserSettings {

    private List<String> securitySettings;  // or any other collection type

    private List<Boolean> forumSettings;

关于java - JPA/Hibernate中的独立表与多余列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45383087/

10-10 03:40