[DB]テーブルをデザインしましょう!2
18118 ワード
たじゅうせい
データベースに基づいて多重性を決定します.
関連付けには対称性があります.
一対多
一対一
ぴったり合った
マルチペア1(N:1)
掲示板と投稿の関係を例に挙げます.
要求
1つの掲示板(1)で複数の投稿(N)を作成できます.
1つの投稿は1つの掲示板にしか書けません.
投稿も掲示板も対日関係です.
データベースベースの多重性が決定された(投稿N:掲示板1).
これは、投稿(N)によって管理される外部キーの一般的な形式です.(データベースは、すべての(N)個の外部キーで構成されている必要があります.)
→多対一(N:1)一方向
@Entity
public class Post {
@Id @GeneratedValue
@Column(name = "POST_ID")
private Long id;
@Column(name = "TITLE")
private String title;
@ManyToOne
@JoinColumn(name = "BOARD_ID")
private Board board;
//... getter, setter
}
@Entity
public class Board {
@Id @GeneratedValue
private Long id;
private String title;
//... getter, setter
}
「複数対1」一方向では、「複数ページPost」に@ManyToOneのみが追加されていることがわかります.逆にBoardは参照しません.(一方的なので)
→多対一(N:1)双方向
@Entity
public class Post {
@Id @GeneratedValue
@Column(name = "POST_ID")
private Long id;
@Column(name = "TITLE")
private String title;
@ManyToOne
@JoinColumn(name = "BOARD_ID")
private Board board;
//... getter, setter
}
@Entity
public class Board {
@Id @GeneratedValue
private Long id;
private String title;
@OneToMany(mappedBy = "board")
List<Post> posts = new ArrayList<>();
//... getter, setter
}
複数のペアを双方向にするには、@OneToManyを(1)ページに追加し、双方向マッピングを使用して、関連する所有者をmappedByと指定します.mappedByとして指定すると、ターゲット変数の名前に基づいて値を指定できます.Postオブジェクト(ターゲット)のboardという変数であるため、boardとして指定されます.
1対多(1:N)
うん.一対多が多対一で反対する立場にあるので、整理する必要はありますか?前述の多対一の基準は関連関係の主人を(N)側に置くことであり,今回言及する一対多の基準は関連関係の主人を(1)側に置くことであると考えられる.
※参考までに実務では一対多(1:N)一方向はほとんど使われていません。
→一対多(1:N)一方向
データベースの観点から、すべての(N)方が外部キーを管理する必要があります。
ただし、マルチ(N)ページオブジェクト(1)ページオブジェクトを操作(作成、変更または削除)する方法.
@Entity
public class Post {
@Id @GeneratedValue
@Column(name = "POST_ID")
private Long id;
@Column(name = "TITLE")
private String title;
//... getter, setter
}
@Entity
public class Board {
@Id @GeneratedValue
private Long id;
private String title;
@OneToMany
@JoinColumn(name = "POST_ID") //일대다 단방향을 @JoinColumn필수
List<Post> posts = new ArrayList<>();
//... getter, setter
}
@OneToManyにmappedByがありません.双方向ではないからです.@JoinColumnを使用して結合します.
実際の使用方法は次のとおりです.
//...
Post post = new Post();
post.setTitle("가입인사");
entityManager.persist(post); // post 저장
Board board = new Board();
board.setTitle("자유게시판");
board.getPosts().add(post);
entityManager.persist(board); // board 저장
//...
上記の場合、postを保存すると挿入クエリーが表示されます.そして問題
Boardを保存すると、Boardを挿入したクエリーが終了すると、postを更新するクエリーが表示されます.
BoardがgetPosts().add(post); 一部の原因で.
BoardエンティティはBoardテーブルにマッピングされるため、Boardテーブルに直接割り当てることができますが、PostテーブルのBOARD IDを保存できないため、クエリーの結合と更新をキャンセルする必要があります.
致命的な欠点
1日しか修正されていないようですが、他の修正があったためクエリーが発生しました.
Boardを保存したのになぜPostが修正したのですか?私にこのような考えを起こさせた.
クエリーの更新により、パフォーマンスの問題はそれほど大きくありません.
したがって,TIPを用いて1対多(1:N)の一方向関連関係マッピングを行う必要がある場合は,多対一(N:1)の双方向関連関係をマッピングするだけで,今後のメンテナンスにおいてより容易になるので,この方法を推奨する.
ただし、実際の操作で使用を禁止しない理由は、使用を避けることが望ましいためですが、代わりにJPA値タイプを使用する場合に便利です.=あまり役に立たない.
→一対多(1:N)双方向(業務使用禁止)
一対多双方向は正式に存在しないので省略します.
キーワードは@JoinColumn(updatable=false、insertable=false)ですが、1対のマルチ双方向を使用する必要がある場合は、マルチペアの双方向を使用することが望ましいです.
🌈 したがって、一対多(1:N)の一方向、双方向を使用するのではなく、多対一(N:1)の双方向使用が正しいと簡単に考えるべきである。
1対1(1:1)
プライマリ・テーブルに外部キーを配置するか、ターゲット・テーブルに外部キーを配置できます.
※一対一(1:1)なので、テーブルA、Bがある場合、Aがメインテーブルであれば、Bがターゲットテーブル、Bがメインテーブルであれば、Aがターゲットテーブルです.
→一対一(1:1)一方向
メインテーブルが持つ意味を外部キーで説明します.(Postテーブル(プライマリテーブル)に外部キー(FK)を使用したAttachテーブル(ターゲットテーブル)のPK)
投稿に添付ファイル(Attach)は1つしか添付できないと仮定します.
@Entity
public class Post {
@Id @GeneratedValue
@Column(name = "POST_ID")
private Long id;
@Column(name = "TITLE")
private String title;
@OneToOne
@JoinColumn(name = "ATTACH_ID")
private Attach attach;
//... getter,setter
}
@Entity
public class Attach {
@Id @GeneratedValue
@Column(name = "ATTACH_ID")
private Long id;
private String name;
//... getter, setter
}
특별할 게 없습니다.
→一対一(1:1)双方向同じ@OneToOneとmappedByを読み取り専用に簡単に設定するだけで、双方向の操作を簡単にすることができます.
@Entity
public class Attach {
@Id @GeneratedValue
@Column(name = "ATTACH_ID")
private Long id;
private String name;
@OneToOne(mappedBy = "attach")
private Post post;
//... getter, setter
}
→一対一(1:1)一方向に対応していない
先ほど整理してみましたが、なぜまた出てきたのでしょうか.今回はPostテーブル(メインテーブル)ではなくAttachテーブル(ターゲットテーブル)で外部キー(FK)を使いたい時を考えてみました.
しかしこのJPAはまったくサポートしていません
→一対一(1:1)双方向
この場合、どちらも一対一なので、上記の定義に従って処理すればよい.
しかし、論争の余地がある.
Postで外部キーを管理するか、Attachで外部キーを管理するかを考えるべきです.つまり、テーブルの上のどの位置に置くかを考えるべきです.
テーブルは、一度作成すると通常硬くなります.つまり変更が難しいということです.
しかし、業務はいつでも変わる可能性があります.
ビジネスが変化した場合、投稿に複数の添付ファイルを添付できます.状況はどうなりますか?
その後、すべての(N)ページのAttachテーブルに外部キーがあり、変更に柔軟です.
では、確率が(N)のテーブルの上に外キーを置くときっといいですか?
それは違います.
オブジェクトの観点から、Post(1)に外部キーがある場合、PostをクエリーするたびにAttachの参照があるため、パフォーマンスが向上します.
※結論
総合的な判断と意思決定が必要ですが、一対一の決定にも慎重であると簡単に仮定すると、プライマリ・テーブルに外部キーを配置したほうがいいです.
もう一度言いますが、これは議論のある意見にすぎません.
マルチペアマルチ(N:N)
業務使用禁止
これは、中間テーブルが非表示であるため、無意識に複雑な結合クエリーが発生する可能性があります.
ほとんどの自動生成された中間テーブルには、2つのオブジェクトのテーブルの外部キーしか格納されていないため、問題が発生する可能性があります.JPAを使用する場合、中間テーブルには通常、キー以外の情報が含まれているため、1対多、多対一の多対多(中間テーブルをエンティティとして作成)の後続の変更を柔軟に処理できます.
出典:https://jeong-pro.tistory.com/231[基本功を積むアマチュアコードブログ]
Reference
この問題について([DB]テーブルをデザインしましょう!2), 我々は、より多くの情報をここで見つけました https://velog.io/@tjdud3550/DB-테이블을-설계하자-2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol