entity-attribute-value あなたが提案するモデルは、このシナリオに適合する可能性があります。
フィルタリングクエリに関しては、EAVモデルを使用すると、クエリの能力が大幅に犠牲になることを理解する必要があります。そのため、これは非常に難しい場合があります。ただし、問題に取り組むためのこの1つの方法:
SELECT stuff.id
FROM stuff
JOIN (SELECT COUNT(*) matches
FROM table
WHERE (`key` = X1 AND `value` = V1) OR
(`key` = X2 AND `value` = V2)
GROUP BY id
) sub_t ON (sub_t.matches = 2 AND sub_t.id = stuff.id)
GROUP BY stuff.id;
このアプローチのエレガントでない機能の1つは、sub_t.matches = 2
で一致すると予想される属性/値のペアの数を指定する必要があることです。 。 3つの条件がある場合、sub_t.matches = 3
を指定する必要があります。 、など。
テストケースを作成しましょう:
CREATE TABLE stuff (`id` varchar(20), `key` varchar(20), `value` varchar(20));
INSERT INTO stuff VALUES ('apple', 'color', 'red');
INSERT INTO stuff VALUES ('mango', 'color', 'yellow');
INSERT INTO stuff VALUES ('banana', 'color', 'yellow');
INSERT INTO stuff VALUES ('apple', 'taste', 'sweet');
INSERT INTO stuff VALUES ('mango', 'taste', 'sweet');
INSERT INTO stuff VALUES ('banana', 'taste', 'bitter-sweet');
INSERT INTO stuff VALUES ('apple', 'origin', 'US');
INSERT INTO stuff VALUES ('mango', 'origin', 'MEXICO');
INSERT INTO stuff VALUES ('banana', 'origin', 'US');
クエリ:
SELECT stuff.id
FROM stuff
JOIN (SELECT COUNT(*) matches, id
FROM stuff
WHERE (`key` = 'color' AND `value` = 'yellow') OR
(`key` = 'taste' AND `value` = 'sweet')
GROUP BY id
) sub_t ON (sub_t.matches = 2 AND sub_t.id = stuff.id)
GROUP BY stuff.id;
結果:
+-------+
| id |
+-------+
| mango |
+-------+
1 row in set (0.02 sec)
次に、color=yellow
を使用して別の果物を挿入しましょう およびtaste=sweet
:
INSERT INTO stuff VALUES ('pear', 'color', 'yellow');
INSERT INTO stuff VALUES ('pear', 'taste', 'sweet');
INSERT INTO stuff VALUES ('pear', 'origin', 'somewhere');
同じクエリが返されます:
+-------+
| id |
+-------+
| mango |
| pear |
+-------+
2 rows in set (0.00 sec)
この結果をorigin=MEXICO
のエンティティに制限する場合 、別のOR
を追加する必要があります 条件を設定し、sub_t.matches = 3
を確認します 2
の代わりに 。
SELECT stuff.id
FROM stuff
JOIN (SELECT COUNT(*) matches, id
FROM stuff
WHERE (`key` = 'color' AND `value` = 'yellow') OR
(`key` = 'taste' AND `value` = 'sweet') OR
(`key` = 'origin' AND `value` = 'MEXICO')
GROUP BY id
) sub_t ON (sub_t.matches = 3 AND sub_t.id = stuff.id)
GROUP BY stuff.id;
結果:
+-------+
| id |
+-------+
| mango |
+-------+
1 row in set (0.00 sec)
すべてのアプローチと同様に、EAVモデルを使用する場合には特定の長所と短所があります。アプリケーションのコンテキストでトピックを広範囲に調査するようにしてください。 Cassandra などの代替のリレーショナルデータベースを検討することもできます。 、 CouchDB 、 MongoDB 、 Voldemort 、 HBase 、 SimpleDB または他のキーバリューストア。