たとえば、Consumers
とMerchants
の2つの異なるタイプの人についてのデータを保存する必要があるとします役割または職業、および両方のタイプロールは、User
と呼ばれる単一のベーステーブルを共有します。
この点で、Merchants
には、CompanyName
、CompanyDescription
などのいくつかの追加フィールドが必要です。
これらの仕様のデータベースを設計するための最も効率的な方法は何ですか?
User
テーブルに追加の列があります。MerchantData
FOREIGNKEYを持つUserId
という追加のテーブルがあります。UserMeta
EAVテーブルを用意して、任意の量の追加値を許可します。追加のフィールドが修正されているため、現在オプション2に傾いています。私が見ていない欠点はありますか?
ConsumersとMerchantsは、Usersすでに述べたように、それらは単一のベーステーブルにある必要があります。
[〜#〜] eav [〜#〜]の実装は、十分に計画され、制御された使用の下で成功する可能性があります。しかし、あなたの質問には、[〜#〜] eav [〜#〜]の解決策が正しい答えであることを意味するものは何もありません。
実際、開発をさらに進めると、Merchantsにいくつかの追加属性があるだけでなく、Consumersにもあることに気付くかもしれません。 )。もしそうなら、あなたは単純なSupertype-Subtypeモデルが欲しいかもしれません。
これにより、以下に示すように関連する3つのテーブルが得られます。
USERS (contains common information) | | ____________|_____________ | | | (details specific to | | a subtype) | Consumers Merchants
これがうまくいく場合、ほとんどの場合、Usersテーブルにのみアクセスしますが、Consumerの追加情報が必要な場合は)またはMerchantこれらの詳細も必要です。
これは非常に単純なアプローチであり、データの不要な重複を回避します。
EAVの実装に関する展望については、Aaron Bertrandの投稿をご覧ください。これは、利点と制限について説明しています。
この場合、要件が急速に変化しているため、EAVの決定が適切な選択となったことに注意してください。
これは古いです、ここに私のより現代的なアドバイスがあります、あなたは追加フィールドでクエリするつもりですか、
現在、MySQLはバイナリJSONタイプを提供しています。 MariaDBは、多くのエラーの1つを認識しており、バイナリJSONフィールドの実装に移行しています。これ大部分がEAVの死を完全に示しているわけではありません。現在、EAVを検討するのは、属性自体がクエリの対象である場合のみです。およびそれらはキーと値のペア。
そして、それはJSONが将来EAVよりも優先されないということではありません。多くのワークロードの下で、PostgreSQLs Gistは競争力のあるクエリを提供したり、EAVのパフォーマンスを上回ったりすることができます。 MySQLが同じ機能を提供するのはほんの数十年のことです。
私はEAVの実装を進めますが、追加のテーブル(AttributeGroup)で属性をさらに装飾します。これは、次のように、レポートと分離の目的で非常に便利です。
Table name: AttributeGroup
Id Name
== ==========
1 Consumer
2 Merchant
3 Something else
次に、属性を持つ1対多のリレーショナルテーブルをもう1つ作成できます。コンセプトを説明するだけですが、例を挙げてほしい場合はお知らせください。