我有一个在我的数据库中建模关系的问题。
我有一个表“评论”和三个表“用户”,“汽车”,“房子”。每个用户都可以评论用户,汽车和房屋。
通常这会产生一种关系,即所有fks都保存在表“注释”中,如car_id,house_id,user_id。但这些关系是独一无二的,所以不可能有一个属于汽车和房子的评论。
现在在评论表中包含所有fks是明智的吗?因此,如果我们想要扩展(例如对图片的评论),可能会导致很多可以为空的fks。
或者为每个关系设置一个新表是一个不错的选择,如“UserComment”,“CarComment”和“HouseComment”。
我希望这不是重复,但我发现很难找到这个问题。
谢谢!
答案 0 :(得分:0)
为了避免冗余并且db中没有必要的空值,我建议使用继承,如果你可以在db中使用它。然后创建名为'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
);
如果您想通过添加新的继承表,可以轻松扩展结构。
答案 1 :(得分: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...