I know the tagging stuff has been mentioned many times, but I can’t seem to see any that address this question.
From this thread
Recommended SQL database design for tags or tagging
I can see the best way to setup tags is likely
Item (item_id, item_content)
Tag (tag_id, tag_title)
TagMapping(map_id, tag_id, item_id)
But what if I want to share the tags between two different item entities? For example, blog posts and articles. (let’s not discuss if that should be separate entities or not :))
Do you do something like this which seems very wrong?
Post (post_id, post_content)
Article (article_id, article_content)
Tag (tag_id, tag_title)
TagMapping(map_id, tag_id, post_id(nullable), article_id(nullable))
The orthodox answer would be to use a table inheritance strategy between Post and Article. Make them both kinds of Item. So (this SQL could be complete nonsense, but you get the idea):
So both articles and posts exist in the item table, and that’s what tags refer to.
You retrieve posts and articles as you do now. If you want to retrieve them by tag, you do a join via Item. If you want to retrieve the details in that join, you have to do an outer join to both Post and Article, and then ignore the null columns.
You very often also have a column in the parent table, here Item, that is like ‘integer subtype_discriminator not null’, which then contains, say, 1 if the item is a post, 2 if it is an article, etc. That makes it a bit easier to know which columns to ignore, or where to look for details if you want to do a second query for them after a simple join.