2012-05-12 21 views
0

リレーショナルデータベース(MySQL)で人物データベースをモデル化する必要があります。EAVへの代替データベース設計

各個人にはプロパティがあります。 1対1の関係(例えば男性/女性)、スポーツや言語(例えば、バスケットボールやフットボールをし、英語とドイツ語を話すなど)のような1対1の関係を有するプロパティが存在する。加えて、これらの1:n関係にはスキルレベルがあります(例:プロフェッショナル、初心者)。

現在、人と特性の関係をモデル化するEAVモデルよりも優れたアプローチがあるかどうかを尋ねています。私の懸念は、主に、特殊な特性を持つ人をより簡単にフィルタリングすることです(例えば、男性であり、職業的にバスケットボールを行うか、初心者であるか、プロフェッショナルで英語を話すすべての俳優)。必ずしも完全に動的である必要はありません)。これは開発者が行う必要があり、テーブルを変更する必要がある場合は問題ありませんが、難しくはありません(SQL文の変更、結合の追加、データベーステーブル/ルックアップテーブルの追加など) 。

私は古典的な列をベースにした設計で、各プロパティの個別の列のpersons表の1:1プロパティを持っています。どのような方法で1:nの関係をモデル化するのが最も良いか分かりません。デザイン:1:nプロパティごとにルックアップと別のテーブルを持つことは避けたい。

最良のアプローチは、以下のEAVアプローチであるように思われる。

列id、nameなどを持つPersonsテーブル。列を持つ

 
1 | Christian 

Aプロパティの表は、例えばプロパティ、値、レベル、PERSON_ID:あなたが事前にデータのスキーマを知らないとき

 
1 | gender | male  | 
1 | sports | basketball | professional 
1 | sports | football | beginner 
1 | language | english | professional 
1 | language | german  | basic 
+0

*「1:nプロパティごとにルックアップと別のテーブルを使用することは避けたい」*なぜそれを避けたいのですか? –

+0

私は2つのコンサートを持っています: – griesi

+0

私は2つのコンサーを持っています - 私は別のテーブルを追加するたびにSQL文を変更する必要があります - 結合を追加してください - ルックアップテーブルと各属性のテーブルは、多くの1:n属性です – griesi

答えて

5

EAVが最も適しているが、あなた開発者に新しいデータセットごとにシステムを変更させたくありません。

あなたが言ったことから、それはここでは当てはまりません。

EAVには多くの欠点があります。たとえば、組み込みのリレーショナルモデルに依存してスキーマを検証することはできません。あなたのユーザ "Christian"が性別を指定する値を持っていない場合、あなたのアプリケーションはそれを処理する必要があります。伝統的なスキーマでは、 "not null"と宣言する性別カラムがあり、 「性別」ルックアップテーブル。これは、ほとんどのアプリケーションにとって大きな問題です。アプリケーションレベルでのデータの妥当性を強制することは簡単なことではありません。

EAVの2番目の大きな欠点は、where句のどこの項目(たとえば、where gender = 'm' ')がサブクエリになるため、SQLを使用すると簡単なクエリが複雑になり、パフォーマンスがかなり低下することです。

私は間違いなくあなたのスキーマを "伝統的な"データベースとして認識しています。ルックアップテーブルを避けたいのであれば、 "性別"テーブルへの外部キーの代わりに、アプリケーションに依存して、有効なオプションが "m"と "f"であることを知ることができます(忘れないでくださいここで起こりうる奇妙なことに対処する - "m"の代わりに "M"が有効ですか?)

1:nの関係をモデル化するために、別のテーブルを作成することができます。 "person_sports"は、 "person"テーブルとの外部キー関係を持ちます。あなたは多分スポーツに対応したルックアップテーブルを持っていて、多分多くの関係があります。

+0

チェック制約を使用して性別を簡単に検証できます –

+0

私はあなたの伝統的なアプローチを十分に理解していません。ジェンダーのような1:1プロパティの場合は簡単ですが、1:nプロパティ(例:スポーツ)のルックアップテーブルとテーブルを避けて、スポーツのような1:nプロパティを追加するにはどうすればよいですか?伝統的なデザインの人のテーブルは、そのようになります id |名前|性別 ## 1 |クリスチャン|男性 スポーツや言語に対する1対nの関係はどのようにモデル化できますか? – griesi

+0

@ user1390721、解説を更新しました。 –

0

質問に対する回答は、実際に何がデータベースに起こるかによって異なります。質問する質問があります:

  • 新しい属性はどのくらいの頻度で追加されますか?
  • 新しい人はどのくらいの頻度で追加されますか?
  • 新しい人を一括で追加するか、一度に1つずつ追加しますか?
  • 検索は、人の属性のほうが多い傾向がありますか、または多くの人の属性のほんのわずかな傾向にありますか?

機能を追加する開発期間があり、開発期間中にデータ構造が安定する場合は、従来のE-Rアプローチを使用します。開発中に、新しい列を追加することは特に厄介ではありません。

また、数十または数百の属性を持つ何百万人ものユーザーを処理する予定がある場合は、パフォーマンスの問題を検討してください。これはあなたをEAVから断つ可能性があります。

人を一括して追加し、一度にいくつかの属性を取得する場合は、非常にうまく機能する代替データベースアプローチがあります。かつて、これは垂直パーティショニングと呼ばれていましたが、現在は列分割という名前が付けられています。この場合、異なる属性を異なるテーブルに格納します。 1-1のアトリビュートには同じプライマリキーが割り当てられます。これにより、ジョインがメモリ内で非常に高速になります。 1-n属性の場合、人物を最初の要素として持つ複合主キーと、デフォルトでは完全ではないデータページが必要です(これにより、同じデータページで更新できます)。

新しい属性を追加するには、新しいテーブルを追加して既存の人物のために追加し、それを使用するデータベースのビューを変更するだけで済みます。

いくつかの商用データベースは、そのような構造(Verticaなど)に特化していますが、mysqlよりもはるかに高価です。

+0

それは私がこの質問をしている理由です。私はEAVを避けたいのですが、各プロパティのルックアップテーブルとテーブルを追加することなく、従来のアプローチで1:nプロパティをどのようにモデル化できるかを見ることはできません。 – griesi

+0

おそらく、1つの特別なテーブルに1:nのプロパティを入れて、他のテーブルを1つのテーブルに入れるのが最良です。各1:nプロパティごとに別々のテーブルが必要で、プロパティ名を列として含めるだけです。特殊な状況下では、EAVまたは垂直パーティショニングの使用は適切です。 –

+0

ok。しかし、1:nプロパティのテーブルは基本的にEAVテーブルと非常によく似ていますが、1:1プロパティはpersonsテーブルに格納されます。これは次のモデルを与えるでしょう。ありがとう 人: id |名前|性別: 1 |クリスチャン|男性 プロパティ person_id |タイプ|値|レベル 1 |スポーツ|バスケットボール|プロフェッショナル 1 |スポーツ|サッカー|初心者 – griesi

関連する問題