Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 476597
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T00:30:21+00:00 2026-05-13T00:30:21+00:00

I was wondering what the best way is to implement a tag system, like

  • 0

I was wondering what the best way is to implement a tag system, like the one used on SO. I was thinking of this but I can’t come up with a good scalable solution.

I was thinking of having a basic 3 table solution: having a tags table, an articles tables and a tag_to_articles table.

Is this the best solution to this problem, or are there alternatives? Using this method the table would get extremely large in time, and for searching this is not too efficient I assume. On the other hand it is not that important that the query executes fast.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T00:30:21+00:00Added an answer on May 13, 2026 at 12:30 am

    I believe you’ll find interesting this blog post: Tags: Database schemas

    The Problem: You want to have a database schema where you can tag a
    bookmark (or a blog post or whatever) with as many tags as you want.
    Later then, you want to run queries to constrain the bookmarks to a
    union or intersection of tags. You also want to exclude (say: minus)
    some tags from the search result.

    “MySQLicious” solution

    In this solution, the schema has got just one table, it is denormalized. This type is called “MySQLicious solution” because MySQLicious imports del.icio.us data into a table with this structure.

    enter image description hereenter image description here

    Intersection (AND)
    Query for “search+webservice+semweb”:

    SELECT *
    FROM `delicious`
    WHERE tags LIKE "%search%"
    AND tags LIKE "%webservice%"
    AND tags LIKE "%semweb%"
    

    Union (OR)
    Query for “search|webservice|semweb”:

    SELECT *
    FROM `delicious`
    WHERE tags LIKE "%search%"
    OR tags LIKE "%webservice%"
    OR tags LIKE "%semweb%"
    

    Minus
    Query for “search+webservice-semweb”

    SELECT *
    FROM `delicious`
    WHERE tags LIKE "%search%"
    AND tags LIKE "%webservice%"
    AND tags NOT LIKE "%semweb%"
    

    “Scuttle” solution

    Scuttle organizes its data in two tables. That table “scCategories” is the “tag”-table and has got a foreign key to the “bookmark”-table.

    enter image description here

    Intersection (AND)
    Query for “bookmark+webservice+semweb”:

    SELECT b.*
    FROM scBookmarks b, scCategories c
    WHERE c.bId = b.bId
    AND (c.category IN ('bookmark', 'webservice', 'semweb'))
    GROUP BY b.bId
    HAVING COUNT( b.bId )=3
    

    First, all bookmark-tag combinations are searched, where the tag is “bookmark”, “webservice” or “semweb” (c.category IN (‘bookmark’, ‘webservice’, ‘semweb’)), then just the bookmarks that have got all three tags searched for are taken into account (HAVING COUNT(b.bId)=3).

    Union (OR)
    Query for “bookmark|webservice|semweb”:

    Just leave out the HAVING clause and you have union:

    SELECT b.*
    FROM scBookmarks b, scCategories c
    WHERE c.bId = b.bId
    AND (c.category IN ('bookmark', 'webservice', 'semweb'))
    GROUP BY b.bId
    

    Minus (Exclusion)
    Query for “bookmark+webservice-semweb”, that is: bookmark AND webservice AND NOT semweb.

    SELECT b. *
    FROM scBookmarks b, scCategories c
    WHERE b.bId = c.bId
    AND (c.category IN ('bookmark', 'webservice'))
    AND b.bId NOT
    IN (SELECT b.bId FROM scBookmarks b, scCategories c WHERE b.bId = c.bId AND c.category = 'semweb')
    GROUP BY b.bId
    HAVING COUNT( b.bId ) =2
    

    Leaving out the HAVING COUNT leads to the Query for “bookmark|webservice-semweb”.


    “Toxi” solution

    Toxi came up with a three-table structure. Via the table “tagmap” the bookmarks and the tags are n-to-m related. Each tag can be used together with different bookmarks and vice versa. This DB-schema is also used by wordpress.
    The queries are quite the same as in the “scuttle” solution.

    enter image description here

    Intersection (AND)
    Query for “bookmark+webservice+semweb”

    SELECT b.*
    FROM tagmap bt, bookmark b, tag t
    WHERE bt.tag_id = t.tag_id
    AND (t.name IN ('bookmark', 'webservice', 'semweb'))
    AND b.id = bt.bookmark_id
    GROUP BY b.id
    HAVING COUNT( b.id )=3
    

    Union (OR)
    Query for “bookmark|webservice|semweb”

    SELECT b.*
    FROM tagmap bt, bookmark b, tag t
    WHERE bt.tag_id = t.tag_id
    AND (t.name IN ('bookmark', 'webservice', 'semweb'))
    AND b.id = bt.bookmark_id
    GROUP BY b.id
    

    Minus (Exclusion)
    Query for “bookmark+webservice-semweb”, that is: bookmark AND webservice AND NOT semweb.

    SELECT b. *
    FROM bookmark b, tagmap bt, tag t
    WHERE b.id = bt.bookmark_id
    AND bt.tag_id = t.tag_id
    AND (t.name IN ('Programming', 'Algorithms'))
    AND b.id NOT IN (SELECT b.id FROM bookmark b, tagmap bt, tag t WHERE b.id = bt.bookmark_id AND bt.tag_id = t.tag_id AND t.name = 'Python')
    GROUP BY b.id
    HAVING COUNT( b.id ) =2
    

    Leaving out the HAVING COUNT leads to the Query for “bookmark|webservice-semweb”.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm just wondering what's the best way to implement a threaded conversation like the
I'm wondering what the best way to implement this would be. Basically our project
In my asp.net mvc 2 app, I'm wondering about the best way to implement
i was wondering what the best way is to implement a hit counter for
I was wondering what would be the best way to implement undirected graphs (and
I was wondering what is the best way or practice to implement the following:
I'm wondering what the best way is to implement a series of different animations.
I'm wondering what is the best way to implement high availability for a self-developed
Whats the best way to implement rollover 'buttons' like Stackoverflow has for 'Questions', 'Tags',
I installed the profile module http://orchardprofile.codeplex.com/ but I am wondering what's the best way

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.