Hibernate 每个关系的数据库模型表?

Hibernate 每个关系的数据库模型表?,hibernate,database-design,jpa,Hibernate,Database Design,Jpa,我的数据库中有一个关于关系建模的问题 我有一个表“评论”和三个表“用户”、“汽车”、“房子”。每个用户都可以评论用户、汽车和房屋 通常情况下,这会导致一种关系,其中所有FK都保存在表“comment”中,如car\u id、house\u id、user\u id。但这些关系是排他性的,因此不可能有属于car和house的注释 现在将所有FK都放在注释表中是否明智?因此,如果我们想要扩展(例如,对图片的评论),可能会导致大量可为空的FK 或者为每个关系(如“UserComment”、“CarCo

我的数据库中有一个关于关系建模的问题

我有一个表“评论”和三个表“用户”、“汽车”、“房子”。每个用户都可以评论用户、汽车和房屋

通常情况下,这会导致一种关系,其中所有FK都保存在表“comment”中,如car\u id、house\u id、user\u id。但这些关系是排他性的,因此不可能有属于car和house的注释

现在将所有FK都放在注释表中是否明智?因此,如果我们想要扩展(例如,对图片的评论),可能会导致大量可为空的FK

或者为每个关系(如“UserComment”、“CarComment”和“HouseComent”)创建一个新表是一个不错的选择

我希望这不是一个重复,但我发现很难搜索这个问题


谢谢大家!

为了避免数据库中的冗余和不必要的空值,我建议使用继承,如果在您使用的数据库中可能的话。然后创建名为“commented_objects”或类似名称的父表,以及从父表继承的具有相同递增顺序的3个表。 在这种情况下,在父表和注释表之间只需要一个引用表

如果数据库不允许继承,可以使用组合和公共序列来模拟继承

所以代码看起来像(对于PostgreSQL):


如果需要,可以通过添加新的继承表来轻松扩展结构。

在Roman的回答中,它不一定是表名。实际上,这是一个鉴别器的概念

所以从表格的角度来看,这看起来像:

create table house ( id .., ..., primary key (id) )
create table user ( id .., ..., primary key (id) )
create table car ( id .., ..., primary key (id) )
create table comment( id ..., commenter ..., commented_id ..., commented_type ... )
有几种方法可以将歧视应用于这样一组关系

首先,您可以使注释本身成为一个层次结构,并使用基于鉴别器的子类化。这种方法的缺点是子类完全没有价值,只满足持久性的需要。这种方法的优点是它可以与任何JPA提供商合作。要使用此方法,您必须:

@Entity
@Table( name="comment" )
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="commented_type")
public abstract class Comment {
    @Id
    @Column( name="id" )
    private Long id;
    ...
}

@Entity
public class HouseComment extends Comment {
    @ManyToOne
    @JoinColumn(name="commented_id")
    private House getHouse();
    ...
}

etc...
就像我说的,有点烦躁

Hibernate特别为您提供了处理此问题的其他选项。例如,使用其“任意”映射的概念:

@Entity
@Table( name="comment" )
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="commented_type")
public abstract class Comment {
    @Id
    @Column( name="id" )
    private Long id;
    ...
}

@Entity
public class HouseComment extends Comment {
    @ManyToOne
    @JoinColumn(name="commented_id")
    private House getHouse();
    ...
}

etc...
@Entity
@Table( name="comment" )
public class Comment {
    @Id
    @Column( name="id" )
    private Long id;

    @Any( metaColumn = @Column( name="commented_type" ) )
    @AnyMetDef(
        idType = "long"
        metaValues = {
            @MetaValue( value="C", targetEntity=Carclass ),
            @MetaValue( value="H", targetEntity=House.class ),
            @MetaValue( value="U", targetEntity=User.class )
        }
    )
    pubic Commentable getCommentTarget { ... }
}

public interface Commentable {
    ...
}

@Entity
public House implements Commentable {
   ...
}

etc...