0

I am storing tags to posts as a many-to-many relationship, like in this post.

I now want to extend tags to be able to tag entities other than posts. I have all these in tables named posts, links, articles, etc. Should I opt for:

tags_items

tag_id | item_id | item_type
-----------------------------
1        2         post
1        42        link
3        7         article

Or create multiple tables

tags_posts
tag_id | post_id 

tags_links
tag_id | link_id 

tags_article
tag_id | article_id 

This forces me to create a new table for every entity I want to tag, but it makes it easier for me to enforce referential integrity.

What are advantages and disadvantages to each approach?

Community
  • 1
  • 1
Aillyn
  • 23,354
  • 24
  • 59
  • 84

2 Answers2

1

Of the two choices I would prefer the second. As you say, it makes R.I. much easier. Another option is to super-type your taggable items. They would need to share an ID scheme, but assuming that the IDs are all completely internal (as any good surrogate key should be) that shouldn't be an issue.

Taggable_Items
    tag_item_id INT (PK)

Posts
    post_id    INT (PK, FK to tag_item_id in Taggable_Items)
    posted_by  INT (FK to your Users table or whatever)
    post_text  VARCHAR(MAX)
    ...

Links
    link_id      INT (PK, FK to tag_item_id in Taggable_Items)
    url          VARCHAR(1000)
    description  VARCHAR(MAX)
    ...

Tags
    tag_id  INT (PK)
    name    VARCHAR(20)

Tagged_Items
    tag_item_id (PK, FK to tag_item_id in Taggable_Items)
    tag_id      (PK, FK to tag_id in Tags)

I hope that's clear enough. Please post a comment if it doesn't make sense.

Tom H
  • 46,766
  • 14
  • 87
  • 128
0

You should take your first option one step further. Instead of item_type as a varchar or char it should be a foreign key to a table of itemtypes.

John
  • 701
  • 6
  • 10