私は、多くの(300K +)オブジェクトのそれぞれについて、さまざまな量(10+)の見積もりを収集し、これらの見積もりの履歴レコードから決定を下すシステムを設計しようとしています。たとえば、オブジェクトのPowerLevelなどを確認しようとする可能性のある、人間による自動化されたプロセスがいくつかあります。これらのプロセスは、互いに優先する(またはしない)結果を報告するため、の履歴を追跡したいと思います。これらのレポートは、プロセスからのメタデータ(日付、チューニングパラメータ、コードバージョンなど)とともに表示されます。具体的には、「エンティティIDでグループ化して、個別の属性ごとに最新の見積もりを検索する」や「属性にコードベース573ae4によって実行された更新があったすべてのエンティティを検索する」などのクエリを実行することができます。
本番環境でエンティティ属性値スキーマを実際に使用したことがない人として、これは、ソースのメタデータ列が追加されたEAVのようなものの完璧なユースケースのようです。具体的には、次のようなテーブルを想定しています。
_entity_id | attribute_id | string_value | numeric_value | datetime_value | discovery_time | discovery_source | discovery_tuning_parameters | discovery_code_hash
_
しかし、 この回答 など、これらのタイプのスキーマに対する多くの批判を耳にしました。非レガシーシステムでEAVを使用している人を見つけるのは難しいので、非常に時代遅れのホイールを再発明するのではないかと非常に躊躇しています...
一方、私が考えることができる他の唯一の選択肢は、完全なNoSQL(bleh)または次のようないくつかの不潔なハイブリッドです。
id | power | power_current_discovery_date | power_current_discovery_source | power_history (an array of hstores?) | foobar | foobar_current_discovery_date | ...
各属性にメタデータが必要になるためです。
何かご意見は?これは、EAVが適している数少ない回数の1つですか?ご協力いただきありがとうございます!
EAVは悪ではありません。他のツールと同様に、実装が不十分で悪用される可能性があります。記事は、カーソル、動的SQL、トリガー、さらにはSQLServer自体をトラッシュトークすることができます。それは彼らを悪いことにはしません。
EAVは適切なソリューションです。あなたの特定のケースでそれが正しい答えであるかどうかは、おそらく何よりも意見に基づいています。誰かがそれが悪いと言ったのであなたが解決策にあなたの心を閉じないことを提案するために私はもっと答えています。考慮すべき反対の視点が常にあります。
サーバー/データベース構成を追跡するためのEAVがあります。データを取得するのに最適ですin。そこに任意のデータをスローでき、ローダーは「E」と「A」が指定されたデータを反映していることを確認します。ただし、Valuesテーブルで数億行を超えると、データの取得outがますます問題になりました。 (400列のPIVOTクエリが100K行を返すことは、それと大いに関係があると思います。)
全体として、私たちは正しい選択をしたと信じています。仕様がほとんどないため、数週間以内に機能システムを起動し、実用的な洞察を提供することができました。要件、レポート、アドホックロード、およびユースケースが解決したので、インタラクティブなニーズを満たすためにデータを「正規化された」テーブルにコピーします。私はEAVの部分を取り除きたくありませんが、それはあまりにも便利です!
ちなみに、INSERTの1つのセットにすべての属性の値が含まれていない場合、「ロールフォワード」クエリ、つまり、その値をいつ収集したかに関係なく、すべての属性の最新の値を取得することもコストがかかります。