0

リレーショナル データベース (MySQL) で個人データベースをモデル化する必要があります。

人にはそれぞれ特徴があります。1:1 の関係のみを持つプロパティ (例: 性別 男性/女性) と、スポーツや言語などの 1:n の関係を持つプロパティ (例: バスケットボールやフットボールをプレーし、英語とドイツ語を話す人) があります。さらに、これらの 1:n 関係にはスキル レベル (プロ、初心者など) があります。

現在、個人と特性の関係をモデル化するために、EAV モデルよりも優れたアプローチがあるかどうかを自問しています。私の主な関心事は、特別なプロパティを持つ人物のフィルタリングを容易にすることです (たとえば、男性であり、(プロとしてバスケットボールをしている、または初心者である) かつ、プロとして英語を話すすべての俳優)。新しいプロパティを簡単に追加できるようにする必要があります (これは、必ずしも完全に動的である必要はありません. 開発者がこれを行う必要があり、テーブルを変更する必要がある場合は問題ありません. しかし、それほど難しくないはずです (例: SQL ステートメントの変更、結合の追加、データベース テーブル/ルックアップ テーブルの追加)。 .

私は従来の列ベースの設計を採用し、persons テーブルの 1:1 プロパティをプロパティごとに別の列に配置します。このような設計で 1:n の関係をモデル化する最良の方法はどれかはわかりません。1:n プロパティごとにルックアップと個別のテーブルを作成することは避けたいと思います。

最良のアプローチは、次の EAV アプローチのようです。

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

1 | キリスト教徒 

列 person_id、property、value、level を持つ Properties テーブル。

1 | 性別 | 男性 |
1 | スポーツ | バスケットボール | プロフェッショナル
1 | スポーツ | サッカー | 初心者
1 | 言語 | 英語 | プロフェッショナル
1 | 言語 | ドイツ語 | 基本
4

2 に答える 2

5

EAVは、データのスキーマが事前にわからず、新しいデータセットごとに開発者にシステムを変更させたくない場合に最適です。

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

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

EAVの2つ目の大きな欠点は、SQLを使用しやすいクエリが非常に複雑になり、where句のすべての項目(「wheregender ='m'」など)がサブクエリになるため、パフォーマンスがかなり急速に低下することです。

したがって、スキーマが「従来の」データベースとして知られているデータを確実にモデル化します。ルックアップテーブルを避けたい場合は、次のことができます。「gender」テーブルへの外部キーを使用する代わりに、アプリケーションを使用して、有効なオプションが「m」と「f」であることを確認できます(忘れないでください)。ここで発生する可能性のある奇妙さに対処するために、「m」ではなく「M」が有効ですか?)

1:nの関係をモデル化するために、「person」テーブルへの外部キー関係を使用して、「person_sports」などの別のテーブルを作成できます。「スポーツ」のルックアップテーブルを作成することもできますし、おそらくそうする必要があります。その場合、多対多の関係になります。

于 2012-05-12T10:35:32.600 に答える
0

あなたの質問に対する答えは、時間の経過とともにデータベースに何が起こるかによって異なります。ここにいくつかの質問があります:

  • 新しい属性はどのくらいの頻度で追加されますか?
  • 新しい人はどのくらいの頻度で追加されますか?
  • 新しい人はまとめて追加されますか、それとも一度に1人ずつ追加されますか?
  • 検索は、人のすべての属性の多くになる傾向がありますか、それとも多くの人のいくつかの属性だけになる傾向がありますか?

機能が追加される開発期間があり、開発期間中にデータ構造が安定する場合は、従来のERアプローチを使用してください。開発中に、新しい列を追加することは特に面倒ではありません。

また、数十または数百の属性を持つ数百万の人々を処理することを計画している場合は、パフォーマンスの問題を検討してください。これにより、EAVを思いとどまらせる可能性があります。

人をまとめて追加し、一度にいくつかの属性を取得する場合に非常にうまく機能する代替データベースアプローチがあります。かつて、これは垂直分割と呼ばれていましたが、現在は列分割という名前で呼ばれているようです。ここでは、さまざまな属性をさまざまなテーブルに格納します。1-1属性は同じ主キーを持ち、これにより、メモリ内で結合が非常に迅速に行われるようになります。これにより、パフォーマンスがほとんど低下します。1-n属性の場合、最初の要素として人を含む複合主キーと、デフォルトでいっぱいではないデータページが必要になります(これにより、同じデータページで更新を行うことができます)。

新しい属性を追加するには、それを格納するための新しいテーブルを追加し、既存のユーザー用にデータを入力し、それを使用するようにデータベースのビューを変更するだけです。

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

于 2012-05-12T16:04:24.987 に答える