8

旅行管理アプリケーションを開発しています。問題のデザインは次のようなものです:

ツアーの各人は旅行者として指定されます。各旅行者はパスポートを持っています。現在、旅行者は、家族の長であるかどうかに応じて、メインメンバーまたはサブメンバーになることができます。MainMemberは、TourPackage、旅行中の家族の合計金額などを決定します。SubMemberは、旅行中はMainMemberに依存します。したがって、MainMemberが削除された場合、そのすべてのSubMemberも削除する必要があります。

つまり、旅行者はパスポートを持っています。(1対1の関係)トラベラーはMainMemberまたはSubMemberのいずれかです。(Traveler-MainMemberとTraveler-SubMemberの間で1対0 / 1)MainMemberには複数のSubMemberが含まれる場合があります。(1対多)サブメンバーには、メインメンバーが1つだけあります。(多対1)

私の現在のERDは次のようなものです。

トラベラーER図

ご覧のとおり、Traveler、MainMember、SubMemberの3つのテーブルは循環依存関係を形成しています。しかし、それが私のアプリケーションを傷つけるかどうかはわかりません。MainMemberであるTravelerを削除すると、1。Travelerのレコードが削除されます。2.関連するMainMemberレコードが削除されます。3.MainMemberに依存するSubMemberレコードが削除されます。4.サブメンバーのTravelerレコードが削除されます。

問題はないようですが、Traveler-MainMemberの削除では、常にTraveler-SubMemberのみが削除されます。それでも、私はこれについて悪い気持ちを持っています。

誰かが私をより良いデザインに導くことができますか?

アップデート -

返事を待っている間に、@Daveoの返事をもとに別のデザインを思いついた。基本的に、Travelerには自己参照外部キーが含まれています。これは、親を識別するためにSubMemberレコードによって使用されます。

これがそのためのERDです。

自己参照テーブルを使用したERD

さて、@ Brankoが指摘したように、以前のデザインでは循環依存の問題がなかったので、どちらのデザインが優れているか知りたいですか?

また、Hibernateを介して実装するのに適した設計はどれですか?2番目のアプローチは、Hibernateを介して実装する際に複雑になる可能性があると思います。

また、好みの設計の実装パターン(Hibernateエンティティでの継承など)に関するいくつかの指針をいただければ幸いです。

4

2 に答える 2

6

ご覧のとおり、3 つのテーブル (Traveler、MainMember、および SubMember) は循環依存関係を形成しています。

いいえ、これは循環依存ではありません。このグラフの「ノード」は、グラフの「エッジ」を適切な方向にたどることによってそれ自体に到達することはできません1。これは、「マージされた」または(プロト)「ダイヤモンド型」の依存関係としてより正確に説明されます。

いいえ、アプリケーションに害はありません。2

「個別のテーブルの各クラス」アプローチを使用して、継承(別名、カテゴリ、サブクラス化、サブタイピング、一般化階層など)を効果的に実装しています。このアプローチはクリーンですが、すぐに使用できるプレゼンス3と排他性4を保証することはできません。そのように修正する方法はありますし、可能な継承のための他の実装戦略もありますが、それらには独自の長所と短所があります。

私の意見では、あなたのモデルはあなたが達成しようとしているものにちょうどよく、アプリケーションレベルで存在/排他性を強制することは、データベースレベルでそれを強制しようとする短所に苦しむよりもおそらく害が少ないでしょう.


1「方向」は、参照から被参照テーブルへの方向です。Travellerも参照しないMainMemberためSubMember、サイクルが中断されます。

2そのような「マージされた」依存関係に対する参照アクションをサポートしていない DBMS (MS SQL Server など) を使用している場合を除きます (この場合、トリガーを介して ON CASCADE DELETE を実装する必要があります)。

3 Travellerは単独では存在できず (「抽象」であってはなりません)、MainMemberまたはでなければなりませんSubMember

4 を と の両方にTravellerすることはできません。MainMemberSubMember

于 2013-02-21T13:16:58.833 に答える
1

データベースには 2 つのテーブルしかありません。

トラベラーとパスワード

Traveler には、Traveler テーブルにリンクして戻る Parent_Id フィールドがあり、メイン/ヘッド トラベラーが誰であるかを格納します。連絡先番号など、メイン/サブメンバーのいずれかに共通するフィールドもこのテーブルに保存します

次に、継承と ORM を使用して、実際のアプリケーションで 2 つの異なるクラスを作成します。MainMember と SubMember MainMember は、Parent_Id が null である Traveler のすべての行になります。 SubMember は、Parent_Id が null でない Traveler のすべての行になります。

于 2013-02-21T10:05:14.743 に答える