0

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

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

通常这会导致所有 fk 都保存在表“注释”中,如 car_id、house_id、user_id。但是这些关系是排他性的,因此不可能有属于汽车和房屋的评论。

现在将所有 fks 都放在评论表中是否明智?因此,如果我们想要扩展(例如图片上的评论),它可能会导致很多可以为空的 fks。

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

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

谢谢!

4

2 回答 2

0

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

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

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

CREATE TABLE commented_objects(
    id int,
    comment text
);


CREATE TABLE cars(
    some_fields text
) INHERITS (commented_objects);


CREATE TABLE houses(
    some_fields text
) INHERITS (commented_objects);

CREATE TABLE users(
    some_fields text
) INHERITS (commented_objects);

CREATE TABLE ref_table(
    id int,
    comment_id
);

如果您愿意,可以通过添加新的继承表轻松扩展结构。

于 2012-10-16T08:15:23.567 回答
0

在 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 ... )

有几种方法可以将歧视应用于这样的一组关系。

首先是您可以使 Comment 本身成为一个层次结构并使用基于鉴别器的子类化。这种方法的缺点是子类完全没有价值,只服务于持久性的需要。这种方法的优点是它可以与任何 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" )
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...
于 2012-10-17T16:17:12.593 回答