Java JPA/Hibernate中的单独表与额外列

Java JPA/Hibernate中的单独表与额外列,java,database,hibernate,jpa,orm,Java,Database,Hibernate,Jpa,Orm,我想知道Hibernate数据库设计的最佳实践 我有一个用户实体,它将有很多不同的设置。对于每一组设置,我要么将它们作为额外的列添加到用户表中,要么创建一个单独的实体,并使用@OneToOne关系将它们连接起来。我的理解是,@OneToMany和@ManyToOne关系通常应该在单独的表中发生,因为您不应该有可选的列 但对于@OneToOne关系来说,这有点不清楚。我认为使用@OneToOne是有道理的,因为默认情况下,ORMs将选择所有单个属性,并且有很多列会减慢这个过程 我所说的一个例子可以

我想知道Hibernate数据库设计的最佳实践

我有一个用户实体,它将有很多不同的设置。对于每一组设置,我要么将它们作为额外的列添加到用户表中,要么创建一个单独的实体,并使用@OneToOne关系将它们连接起来。我的理解是,@OneToMany和@ManyToOne关系通常应该在单独的表中发生,因为您不应该有可选的列

但对于@OneToOne关系来说,这有点不清楚。我认为使用@OneToOne是有道理的,因为默认情况下,ORMs将选择所有单个属性,并且有很多列会减慢这个过程

我所说的一个例子可以用下面的例子来说明

@Entity
public class User{

@OneToOne
private ForumSettings forumSettings;

@OneToOne
private AccountSettings accountSettings;

@OneToOne
private SecuritySettings securitySettings;

}
vs

上面是一个简单的例子来展示这个概念,但实际上第二部分中会有更多的专栏

我知道这可能是基于观点的,但我希望有人能分享这两种选择的利弊


非常感谢

您的问题一般是关于数据规范化的。规范化本身是一个广泛的研究领域,基本上是一种构造数据库表的方法,避免冗余,确保更新不会引入异常

规范化的第一条规则是表中不应包含重复的组。在你的情况下是这样的

解决方案1:将用户设置存储为实体,将其映射为一对一关系

    @Entity
    public class User

    @OneToMany
    private List<UserSettings> userSettings;
这种方法的优点是,
UserSettings
将拥有自己的持久性标识,并且可以由自己查询。它不依赖于父母。 例如:

 SELECT q from Query q where ...

解决方案2:将设置存储在基本元素集合中

您可以在集合中存储用户设置(每个用户都有自己的设置集)

UserSettings在单独的类中,但存储在
User
表中

@Embeddable
public class UserSettings {

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

    private List<Boolean> forumSettings;
@可嵌入
公共类用户设置{
私有列表安全设置;//或任何其他集合类型
个人设置列表;

还有属性。为什么不创建基本
设置
类,然后将属性
类型
添加到
设置
类?然后
用户
设置
之间的关联可以是
一个域
。一般来说,这更多的是数据库设计问题,而不是实现问题(jpa,hibernate)。你要问的是如何规范化数据。我不明白这将如何工作。每个“用户设置”的列数has是一个固定的数字。但可能帐户设置有4个属性,安全设置有3个属性,论坛设置有7个属性…等等。事实上,我想我误解了你的答案。我想你的意思是“用户设置”(不是复数)每个UserSetting都是设置类型及其值的键/值对。但这将强制所有值都属于相同的类型,例如StringUserSettings只有一列-
属性
,每个属性都是单独的行(如果您只有3到7个属性)非常感谢您提供的所有选项!我将在接下来的几天内仔细研究它们。
 SELECT q from Query q where ...
   @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<>();
@Entity
public class User {

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

    private String name;

    ...

    @Embedded
    private UserSettings userSettings;
@Embeddable
public class UserSettings {

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

    private List<Boolean> forumSettings;