0

データベースで関係をモデル化する質問があります。

テーブル「コメント」と、「ユーザー」、「車」、「家」の 3 つのテーブルがあります。すべてのユーザーは、ユーザー、車、家についてコメントできます。

通常、これはすべての fk が car_id、house_id、user_id のようなテーブル「コメント」に保持される関係になります。ただし、これらの関係は排他的であるため、車と家に属するコメントを持つことはできません。

コメントテーブルにすべてのfkを入れるのは賢明ですか? したがって、拡張したい場合 (例: 写真へのコメント) は、多くの null 許容 fk になる可能性があります。

それとも、「UserComment」、「CarComment」、「HouseComment」などの関係ごとに新しいテーブルを用意するのが良い選択ですか。

これが重複していないことを願っていますが、この問題を検索するのは非常に困難でした.

ありがとうございました!

4

2 に答える 2

0

ローマンの回答では、必ずしもテーブル名である必要はありません。本当にそこにある考えは弁別者のそれです。

したがって、テーブルに関しては、これは次のようになります。

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

このような一連の関係に差別を適用する方法はいくつかあります。

1つは、コメント自体を階層にして、識別子ベースのサブクラス化を使用できることです。このアプローチの短所は、サブクラスが完全に無価値であり、永続性のニーズのみを提供することです。このアプローチの長所は、どの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 に答える
0

冗長性と不要なnullを回避するために、使用するdbで可能な場合は、継承を使用することをお勧めします。次に、「commented_objects」などの名前の親テーブルと、同じ増分シーケンスで親テーブルから継承する3つのテーブルを作成します。この状況では、親テーブルとコメントテーブルの間に必要な参照テーブルは1つだけです。

構成と共通シーケンスを使用して、データベースで継承が許可されていない場合は、継承をシミュレートできます。

したがって、コードは次のようになります(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 に答える