2

はじめに

私はEAVデータベースについて読んでいますが、短所のほとんどは、本当に、本当に、悪いEAV設計またはデータからレポートを生成するのが難しいことに関連しているようです.

通常、人々が EAV について不平を言っているのを見るとき、彼らは RDBMS の個別のテーブル + 列の機能を複製しようとして 3 つ未満のテーブルを使用しています。場合によっては、10 進数から文字列まですべてを 1 つのTEXT値列に格納することを意味します。EAV はまた、注意しないと非常に悪いデータの整合性に対するセーフ ガードを台無しにします。

ただし、EAV は履歴データを追跡する簡単な方法を提供し、システムの一部を SQL とキー バリュー ストア システムの間で行き来させることができます。

タイプに基づいて異なるエンティティ属性を分離するとどうなるでしょうか。これにより、特定の属性とエンティティに関連付けられた適切にインデックス化された値に加えて、begsTo、Has、HasMany、および HasManyThrough 関係を引き続き処理できます。

次の 2 つの基本エンティティを考慮する

products (price -> decimal, title -> string, desc -> text, etc...)
    attributes
        options
            [...]
        int
        datetime
        string
        text
        decimal
        relation
            [id,foreign_key]

users (gender -> options, age -> int, username -> string, etc...)
    attributes
        options
            [...]
        int
        datetime
        string
        text
        decimal
        relation
            [id,foreign_key]

RDBMS スキーマ設計

ご存知のように、ユーザー プロファイルと製品は、世界で最も多様なアイテムの一部です。各企業はそれらを異なる方法で処理し、ニーズに合わせて異なる「列」または「属性」を持っています。

以下は、複数の (ネストされたおよび/またはリレーショナルな) エンティティを処理する方法のビューです。

アイデアは、エンティティごとにこのマスター属性テーブルがあり、それらの値を見つけて解釈する方法を指定するというものです。これにより、他のエンティティへの外部キーや、「オプション」や 10 進数などの特殊なケースを処理できます。

entity_type { id, type, // つまり、「ブログ」、「ユーザー」、「製品」など.. created_at }

entity {
    id,
    entity_type_id, 
    created_at
}

    attr {
        id,
        entity_id,
        type,
        name,
        created_at
    }

        option {
            id,
            attr_id,
            entity_id,
            multiple, // multiple values allowed?
            name,
            created_at
        }

        attr_option {
            id
            attr_id,
            entity_id,
            option_id
            option,
            created_at
        }

        attr_int {
            attr_id,
            entity_id,
            int,
            created_at
        }

        attr_relation {
            attr_id,
            entity_id,
            entity_fk_id,
            created_at
        }

        attr_datetime {
            attr_id,
            entity_id,
            datetime,
            created_at
        }

        attr_string {
            attr_id,
            entity_id,
            var_char,
            created_at
        }

        attr_text {
            attr_id,
            entity_id,
            text,
            created_at
        }

        attr_decimal {
            attr_id,
            entity_id,
            decimal,
            created_at
        }

このようなテーブルを使用すると、値を変更する新しい属性ごとに を追加して、最新の値が何であるかを知ることがUPDATE ...できるため、その必要がなくなります。これは、履歴データの記録を保持するのに最適です (もちろん例外はあります)。INSERT INTO ...created_at

サンプルクエリ

まず、エンティティの「タイプ」は何ですか?(ユーザー、投稿、コメントなど)

SELECT * FROM entity_type et LEFT JOIN entity e ON e.entity_type_id = et.id WHERE e.id = ?

次に、このエンティティの属性は何ですか? (テーブル属性)

SELECT * FROM attr WHERE entity_id = ?

次に、このエンティティの属性にはどのような値が存在しますか? (attr_### テーブル)

SELECT * FROM attr_option, attr_int, attr_relation, attr_text, ... WHERE entity_id = ?
vs
SELECT * FROM attr_option WHERE entity_id = ? if( ! multiple) ORDER BY created_at DESC LIMIT 1
SELECT * FROM attr_int WHERE entity_id = ? ORDER BY created_at DESC LIMIT 1
SELECT * FROM attr_relation WHERE entity_id = ? ORDER BY created_at DESC LIMIT 1
SELECT * FROM attr_text WHERE entity_id = ? ORDER BY created_at DESC LIMIT 1
...

このエンティティにはどのような関係が存在しますか?

ID が 34 の「投稿」エンティティがあり、その「コメント」が必要であると仮定すると (entity_type = 2)、これにより、製品エンティティのコメント エンティティ ID を取得できます。

SELECT * FROM entity AS e
LEFT JOIN attr_relation AS ar ON ar.entity_id = e.id
WHERE ar.entity_id = 34 AND e.entity_type = 2;

複数のクエリ (いずれにしてもキー値ストアで必要) は別として、このアプローチにはどのような問題が存在するでしょうか?

4

3 に答える 3

6

EAV「データベース」[原文のまま] は、文字通り 数学的に 単純明快に、データベースとそのメタデータのトリプルで文​​書化されていない記述であり、関係を集計したり、関係を照会したり、メタデータを照会したり、型チェックを行ったり、整合性を維持したり、最適化したりする機能はありません。またはアトミックにトランザクションを実行するか、同時実行を制御します。

ソフトウェア エンジニアリングの原則では、適切な EAV データベース [原文ママ] の使用は、DBMS の機能を再構築する適切な抽象化 (型、演算子、プロセス、インタープリター、モジュール) を定義することだけで構成されると規定されています。

EAV トリプルとその意味から (断片化された) データベース記述へのマッピングの機械的性質により、これを簡単に示すことができます。

Greenspunを言い換えると、十分に複雑な EAV プロジェクトには、その場しのぎで、非公式に指定され、バグが多く、DBMS の半分の遅い実装が含まれています。

繰り返しますが、EAV はデータベースとそのメタデータを 3 つに分けた文書化されていない記述であり、DBMS はありません。DDL ソリューションがパフォーマンス要件を満たすことができないこと、および EAV ソリューションが可能であり、その価値があることを実証したデータベースの部分にのみ EAV を使用してください。

于 2014-05-30T09:06:57.067 に答える