3

以下は、私の問題を表すデータベース設計です (実際のデータベース設計ではありません)。都市ごとに、利用可能なレストラン、バー、ホテルを知る必要があります。2 つのデザインがそれ自体を物語っていると思いますが、

最初の設計: 都市とレストラン、バー、ホテルの間に 1 対多の関係を作成します。

2 番目の設計: 都市と場所の間に 1 対多の関係のみを作成します。

どの設計がベスト プラクティスでしょうか? 2 番目の設計は関係が少ないですが、ある都市のすべてのレストラン、バー、ホテルを取得し、そこに独自のデータ (property_x/y/z) を取得できますか?

更新:この質問は間違っています。明確でないのは私のせいかもしれません。

  • レストラン/バー/ホテルのクラスは、「場所」のサブクラスです (両方の設計で)。
  • レストラン/バー/ホテルのクラスには、親の「場所」が必要です
  • レストラン/バー/ホテル クラスには固有のデータ (property_X/Y/X) があります。

データベース設計

4

6 に答える 6

3

まず良いデザイン

データ、および SQL と ERD の読みやすさ/わかりやすさは、考慮すべき最も重要な要素です。読みやすさのために:

  • に入れcity_idますplace。理由: 場所は都市にあります。ホテルは、ホテルであるという理由だけでたまたま都市にある場所ではありません。

考慮すべきその他の設計ポイントは、この構造が将来どのように拡張されるかです。新しいサブタイプの追加を比較してみましょう:

  • デザイン 1 では、新しいテーブル、「場所」への関係、およびへの関係を追加する必要があります。city
  • 設計 2 では、新しいテーブルと関係を「場所」に追加するだけです。

私は再び2番目のデザインに行きます。

パフォーマンスセカンド

さて、私は推測しcity_idていますが、サブタイプを入れる理由はおそらく、特定のユースケースでより効率的または高速であると予想されるためであり、これは読みやすさ/理解可能性を無視する非常に良い理由かもしれません. ただし、展開する実際のハードウェアでパフォーマンスを測定するまで、次のことはわかりません。

  • どちらのデザインが速いですか
  • パフォーマンスの違いが実際にシステム全体を低下させるかどうか
  • 他の最適化アプローチ (SQL またはデータベース パラメーターのチューニング) が実際にそれを処理するためのより良い方法であるかどうか。

設計 1 は、データベースを ERD で物理的にモデル化する試みであり、これは悪い習慣であると私は主張します。

時期尚早の最適化は、SW エンジニアリングにおける多くの問題の根源です。

サブタイプアプローチ

ERD にサブタイプを実装するには、次の 2 つの解決策があります。

  1. 共通プロパティ テーブル、およびサブタイプごとに 1 つのテーブル (これが 2 番目のモデルです)
  2. サブタイプ プロパティ用の追加の列を含む単一のテーブル。

単一テーブルのアプローチでは、次のようになります。

  • サブタイプ列TYPE INT NOT NULL. 行がレストラン、バー、ホテルのいずれであるかを指定します
  • 余分な列property_Xproperty_Yおよびproperty_Zplace

長所と短所の簡単な表を次に示します。

単一テーブル アプローチの欠点:

  • 単一テーブル アプローチでは、拡張列 (X、Y、Z) を NOT NULL にすることはできません。行レベルの制約を実装できますが、単純な NOT NULL の単純さと可視性が失われます
  • 特に追加のサブタイプを追加すると、単一のテーブルは非常に広く疎になります。最大に達する可能性があります。一部のデータベースの列数。これにより、この設計は非常に無駄になります。
  • 特定のサブタイプのリストを照会するには、WHERE TYPE = ?句を使用してフィルタリングする必要がありますが、サブタイプごとのテーブルははるかに自然です `FROM HOTEL INNER JOIN PLACE ON HOTEL.PLACE_ID = PLACE.ID"
  • 私見、オブジェクト指向言語のクラスへのマッピングは難しく、あまり明白ではありません。この DB が Hibernate、Entity Beans などによってマップされる場合は回避することを検討してください

単一テーブル アプローチの利点:

  • 単一のテーブルに統合することで、結合がなくなるため、クエリと CRUD 操作がより効率的になります (ただし、このわずかな違いが問題になるのでしょうか?)
  • さまざまなタイプのクエリはパラメータ化されているため( WHERE TYPE = ?)、SQL 自体ではなくコードでより制御しやすくなっています ( FROM PLACE INNER JOIN HOTEL ON PLACE.ID = HOTEL.PLACE_ID)。

最適な設計はありません。最も頻繁に実行する SQL および CRUD 操作の種類に基づいて選択する必要があり、場合によってはパフォーマンスに基づいて選択する必要があります (ただし、一般的な警告については上記を参照してください)。

アドバイス

すべてが同じであれば、デフォルトのオプションは 2 番目のデザインにすることをお勧めします。ただし、上に挙げたような重大な懸念がある場合は、別の実装を選択してください。ただし、時期尚早に最適化しないでください。

于 2013-02-04T09:48:39.837 に答える
0

最良の選択肢は2番目の選択肢だと思います。最初の設計では、ある場所を1つの都市(Aなど)の特定のレストラン(または他のタイプ)に割り当てると同時に、別の都市の別のレストランに割り当てることができるため、データエラーが発生する可能性があります。 (例:B)。2番目のデザインでは、場所は常に特定の都市にバインドされています。

于 2013-02-01T19:02:19.083 に答える
0

まず、
どちらの設計でも、適切なデータをすべて取得できます。

2番目:
すべての拡張クラスが場所を実装する場合(実装にとって明らかなように聞こえます)、親オブジェクトの一部としてそれを含めることをお勧めします。これはオプション2を提案します

。Thingy:
問題は、特定の各PLACEのタイプを見つけることはできても、タイプ(CHILD)が常に場所(PARENT)であることを知っている方が簡単なことです。オプション2の結果セットを視覚化するときに、そのことを考えることができます。それを念頭に置いて、最初のアプローチをお勧めします。

注:
最初のものはそれ以上の関係を持っていません、それはそれらを分割するだけです。

于 2013-02-07T03:40:32.243 に答える
0

バー、レストラン、ホテルの属性のセットが異なる場合、それらは異なるエンティティであり、3つの異なるテーブルで表す必要があります。しかし、なぜプレーステーブルが必要なのですか?私はそれを捨てて、あなたの3つのエンティティのために3つのテーブルを持っていることをアドバイスします、そしてそれはそれです。

コードでは、共通の属性を親クラスに収集することは、もちろん、各子クラスでそれらを繰り返すよりも組織的で効率的です。しかし、上記のspathiranaのコメントのように、データベース設計はOOPのようなものではありません。もちろん、場所の一般的な属性を「場所」テーブルに貼り付けることで、列名の繰り返しを節約できます。ただし、複雑さも増します。-バー、レストラン、またはホテルを参照する場合は常にそのテーブルに参加する必要があります-新しいバー、レストラン、またはホテルを追加する場合は常に2つのテーブルに挿入する必要があります- ...などの場合に2つのテーブルを更新します。

プレーステーブルなしで3つのテーブルを使用することも、おそらく最もパフォーマンスが最適な設計です。しかし、それは私がどこから来たのかではありません。私は、単一のエンティティが単一のテーブルの単一の行を意味する、クリーンでシンプルなデータベース設計を考えています。リレーショナルDBには「is-a」関係はありません。外部キー関係は「has-a」です。確かに例外はありますが、あなたの場合も例外ではありません。

于 2013-02-07T15:45:53.223 に答える
0

どのサブプレース テーブルにも代替列を表示しません。タイプデータを「バー」、「レストラン」などのテーブル名に分割するべきではないと思います-これらはプレイステーブル内のタイプでなければなりません。

さらに、住所テーブルが必要だと思います-その1つの列は都市です。次に、各場所に住所があり、必要に応じて都市ごとに簡単にグループ化できます. (または州、郵便番号、国など)

于 2013-02-01T18:58:32.627 に答える
0

それらの両方とそれらのどれもまったくありません。

1 つを選択する必要がある場合は、後で作成する必要がある外部キーとインデックスの数があるため、2 つ目を保持します。
しかし、より良い方法は次のとおりです。すべての種類の場所 (バー、レストランなど) を含むテーブルを作成し、場所のタイプの値を持つ列を各行に割り当てます (予想されるタイプのCOMPRESS句を適用します)。列で)。これにより、構造のパフォーマンスと可読性の両方が向上し、さらに保守がより簡単になります。

お役に立てれば。:-)

于 2013-02-01T18:42:21.387 に答える