thực thể-thuộc tính-giá trị mô hình mà bạn đề xuất có thể phù hợp với trường hợp này.
Về truy vấn lọc, bạn phải hiểu rằng với mô hình EAV, bạn sẽ hy sinh nhiều sức mạnh truy vấn, vì vậy điều này có thể trở nên khá phức tạp. Tuy nhiên, đây là một cách để giải quyết vấn đề của bạn:
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;
Một tính năng không phù hợp của phương pháp này là bạn cần chỉ định số lượng cặp thuộc tính / giá trị mà bạn muốn khớp trong sub_t.matches = 2
. Nếu có ba điều kiện, chúng tôi sẽ phải chỉ định sub_t.matches = 3
, và như vậy.
Hãy xây dựng một trường hợp thử nghiệm:
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');
Truy vấn:
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;
Kết quả:
+-------+
| id |
+-------+
| mango |
+-------+
1 row in set (0.02 sec)
Bây giờ, hãy chèn một quả khác có color=yellow
và taste=sweet
:
INSERT INTO stuff VALUES ('pear', 'color', 'yellow');
INSERT INTO stuff VALUES ('pear', 'taste', 'sweet');
INSERT INTO stuff VALUES ('pear', 'origin', 'somewhere');
Cùng một truy vấn sẽ trả về:
+-------+
| id |
+-------+
| mango |
| pear |
+-------+
2 rows in set (0.00 sec)
Nếu chúng ta muốn giới hạn kết quả này cho các thực thể có origin=MEXICO
, chúng tôi sẽ phải thêm một OR
khác điều kiện và kiểm tra sub_t.matches = 3
thay vì 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;
Kết quả:
+-------+
| id |
+-------+
| mango |
+-------+
1 row in set (0.00 sec)
Như trong mọi cách tiếp cận, có những ưu và nhược điểm nhất định khi sử dụng mô hình EAV. Đảm bảo rằng bạn nghiên cứu chủ đề sâu rộng trong bối cảnh ứng dụng của bạn. Bạn thậm chí có thể muốn xem xét một cơ sở dữ liệu quan hệ thay thế, chẳng hạn như Cassandra , CouchDB , MongoDB , Voldemort , HBase , SimpleDB hoặc các cửa hàng khóa-giá trị khác.