Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The <a href="http://en.wikipedia.org/wiki/Entity-attribute-value_model" rel="nofollow noreferrer">entity-attribute-value</a> model that you suggest could fit in this scenario.</p> <p>Regarding the filtering query, you have to understand that with the EAV model you will sacrifice plenty of query power, so this can become quite tricky. However this one way to tackle your problem:</p> <pre><code>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; </code></pre> <p>One inelegant feature of this approach is that you need to specify the number of attribute/value pairs that you expect to match in <code>sub_t.matches = 2</code>. If we had three conditions we would have had to specify <code>sub_t.matches = 3</code>, and so on.</p> <p>Let's build a test case:</p> <pre><code>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'); </code></pre> <p>Query:</p> <pre><code>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; </code></pre> <p>Result:</p> <pre><code>+-------+ | id | +-------+ | mango | +-------+ 1 row in set (0.02 sec) </code></pre> <p>Now let's insert another fruit with <code>color=yellow</code> and <code>taste=sweet</code>:</p> <pre><code>INSERT INTO stuff VALUES ('pear', 'color', 'yellow'); INSERT INTO stuff VALUES ('pear', 'taste', 'sweet'); INSERT INTO stuff VALUES ('pear', 'origin', 'somewhere'); </code></pre> <p>The same query would return:</p> <pre><code>+-------+ | id | +-------+ | mango | | pear | +-------+ 2 rows in set (0.00 sec) </code></pre> <p>If we want to restrict this result to entities with <code>origin=MEXICO</code>, we would have to add another <code>OR</code> condition and check for <code>sub_t.matches = 3</code> instead of <code>2</code>.</p> <pre><code>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; </code></pre> <p>Result:</p> <pre><code>+-------+ | id | +-------+ | mango | +-------+ 1 row in set (0.00 sec) </code></pre> <p>As in every approach, there are certain advantages and disadvantages when using the EAV model. Make sure you research the topic extensively in the context of your application. You may even want to consider an alternative relational databases, such as <a href="http://cassandra.apache.org/" rel="nofollow noreferrer">Cassandra</a>, <a href="http://couchdb.apache.org/" rel="nofollow noreferrer">CouchDB</a>, <a href="http://www.mongodb.org/" rel="nofollow noreferrer">MongoDB</a>, <a href="http://project-voldemort.com/" rel="nofollow noreferrer">Voldemort</a>, <a href="http://hadoop.apache.org/hbase/" rel="nofollow noreferrer">HBase</a>, <a href="http://aws.amazon.com/simpledb/" rel="nofollow noreferrer">SimpleDB</a> or other key-value stores.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload