entity-attribute-value model yang Anda sarankan cocok dengan skenario ini.
Mengenai kueri pemfilteran, Anda harus memahami bahwa dengan model EAV Anda akan mengorbankan banyak daya kueri, jadi ini bisa menjadi sangat rumit. Namun satu cara ini untuk mengatasi masalah Anda:
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;
Salah satu fitur yang tidak tepat dari pendekatan ini adalah Anda perlu menentukan jumlah pasangan atribut/nilai yang Anda harapkan untuk dicocokkan di sub_t.matches = 2
. Jika kita memiliki tiga kondisi, kita harus menentukan sub_t.matches = 3
, dan seterusnya.
Mari buat kasus uji:
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');
Pertanyaan:
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;
Hasil:
+-------+
| id |
+-------+
| mango |
+-------+
1 row in set (0.02 sec)
Sekarang mari kita masukkan buah lain dengan color=yellow
dan taste=sweet
:
INSERT INTO stuff VALUES ('pear', 'color', 'yellow');
INSERT INTO stuff VALUES ('pear', 'taste', 'sweet');
INSERT INTO stuff VALUES ('pear', 'origin', 'somewhere');
Kueri yang sama akan kembali:
+-------+
| id |
+-------+
| mango |
| pear |
+-------+
2 rows in set (0.00 sec)
Jika kita ingin membatasi hasil ini pada entitas dengan origin=MEXICO
, kita harus menambahkan OR
. lainnya kondisi dan periksa sub_t.matches = 3
bukannya 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;
Hasil:
+-------+
| id |
+-------+
| mango |
+-------+
1 row in set (0.00 sec)
Seperti dalam setiap pendekatan, ada keuntungan dan kerugian tertentu saat menggunakan model EAV. Pastikan Anda meneliti topik secara ekstensif dalam konteks aplikasi Anda. Anda bahkan mungkin ingin mempertimbangkan database relasional alternatif, seperti Cassandra , CouchDB , MongoDB , Voldemort , HBase , SimpleDB atau penyimpanan nilai kunci lainnya.