Note that there are some explanatory texts on larger screens.

plurals
  1. POWill this (normalised) database structure permit me to search by tags as I intend?
    primarykey
    data
    text
    <p>I am trying to set up a normalised MySQL database containing the three following tables. The first table contains a list of items which can be described by various tags. The third table contains the various tags used to describe the items in the first table. The middle table relates the other two tables to each other. In each table's case, the id is an auto-incrementing primary key (and each is used as the foreign key in the middle table)</p> <pre><code>+---------------+---------------------+---------------+ | Table 1 | Table 2 | Table 3 | +---------------+---------------------+---------------+ |id item |id item_id tag_id|id tag| +---------------+---------------------+---------------+ | 1 spaniel| 1 1 4| 1 bird| | 2 tabby| 2 1 23| 4 pet| | 3 chicken| 3 1 41|23 dog| | 4 goldfish| 4 2 4|24 cat| | | 5 2 24|25 reptile| | | 6 3 1|38 fish| | | 7 3 40|40 delicious| | | 8 4 4|41 cheap| | | 9 4 38|42 expensive| | |10 4 41| | | | | | +---------------+---------------------+---------------+ </code></pre> <p>I want to run a query of one ore more tags against the three tables to return the items that match ALL of the tags.</p> <p>So for example, querying for "pet" would return the items (1)spaniel, (2)tabby and (4)goldfish, because all of them are tagged "pet". Querying for "cheap" and "pet" together would return (1)spaniel and (4)goldfish because they are both tagged "cheap" and "pet". Tabby would not be returned as it is only tagged "pet" but not "cheap" (in my world tabby cats are expensive :P)</p> <p>Querying for "cheap", "pet" and "dog" would only return (1)Spaniel, since it is the only one matching all three tags.</p> <p>Anyway, this is the desired behaviour. I have two questions.</p> <blockquote> <ol> <li><p>Is this the best way to set up my tables for my intended purposes? I am still new to ideas of normalising databases, and am picking this up as I go along - any input on efficiency or even if this is an appropriate layout for my database would be much appreciated. </p></li> <li><p>Provided the above setup is workable, how could I structure a single MySQL query to achieve my intended purpose?* (that being, for a series of tags, returning ONLY the item(s) that match ALL the specified tags). I have tried doing a variety of JOINs/UNIONs but none of them are giving me the desired effect(usually return ALL the items that match ANY of the tags). I've spent some time looking through the MySQL manual online but I feel like I'm missing something conceptually.</p></li> </ol> </blockquote> <p>*I say single query since of course I could just run a series of simple WHERE/JOIN queries, one for each tag and then combine/sort the returned items in PHP or something after the fact but it seems a foolish and inefficient way of doing it. I feel like there is a way I should be able to do this with a single MySQL query, given the appropriate setup.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    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.
 

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