patternsqlMinor
Schema for allowing adding tags to entities in unrelated tables
Viewed 0 times
allowingtablesunrelatedaddingtagsforentitiesschema
Problem
I'm implementing a "tags" features to an already working solution.
Final users need to be able to add tags to three separate sections of the solution:
Each section has its corresponding table in the database, and each table contains a unique ID:
I'm thinking about implementing a tag schema similar to the one that Wordpress uses, where I'll have:
I like this approach because it is decently normalized, but queries might get a bit complex. Also, it will have a lot of
Is there a better alternative to this?
Final users need to be able to add tags to three separate sections of the solution:
Posts
Accounts
Groups
Each section has its corresponding table in the database, and each table contains a unique ID:
PostID
AccountID
GroupID
I'm thinking about implementing a tag schema similar to the one that Wordpress uses, where I'll have:
- A
tagmaptable that will contain a unique ID for each "tagmap".
- A foreign key to each section's table ID.
- Another foreign key to the ID of the tag.
CREATE TABLE Posts(
PostID int(2) NOT NULL AUTO_INCREMENT,
Content varchar(255),
PRIMARY KEY(PostID)
);
CREATE TABLE Groups(
GroupID int(2) NOT NULL AUTO_INCREMENT,
GroupName varchar(255),
PRIMARY KEY(GroupID)
);
CREATE TABLE Links(
LinkID int(2) NOT NULL AUTO_INCREMENT,
href varchar(255),
PRIMARY KEY(LinkID)
);
CREATE TABLE tagmap(
TagmapID int(2) NOT NULL AUTO_INCREMENT,
PostID int(2),
GroupID int(2),
LinkID int(2),
TagID int(2) NOT NULL,
PRIMARY KEY(TagmapID)
);
CREATE TABLE tags(
TagID int(2) NOT NULL AUTO_INCREMENT,
TagName varchar(255) NOT NULL,
PRIMARY KEY(TagID)
);I like this approach because it is decently normalized, but queries might get a bit complex. Also, it will have a lot of
NULL columns every time a tag is assigned to a post but not to an account or to a group, so I'm unsure how it will behave performance-wise (the table will hold around 100,000 records almost immediately). Is there a better alternative to this?
Solution
A simple solution is to include a table reference in the tagmap instead of many id columns.
With that approach, you can easily make other tables taggable. To retrieve the tags for a post, you'd just say
CREATE TABLE tagmap(
TagmapID int(2) NOT NULL AUTO_INCREMENT,
RefTable varchar(255) NOT NULL,
RefID int(2),
TagID int(2) NOT NULL,
PRIMARY KEY(TagmapID),
INDEX(RefTable, RefID),
UNIQUE(RefTable, RefID, TagID)
);With that approach, you can easily make other tables taggable. To retrieve the tags for a post, you'd just say
SELECT TagName FROM tags
LEFT JOIN tagmap USING TagID
WHERE RefTable = 'posts' AND RefID = 42Code Snippets
CREATE TABLE tagmap(
TagmapID int(2) NOT NULL AUTO_INCREMENT,
RefTable varchar(255) NOT NULL,
RefID int(2),
TagID int(2) NOT NULL,
PRIMARY KEY(TagmapID),
INDEX(RefTable, RefID),
UNIQUE(RefTable, RefID, TagID)
);SELECT TagName FROM tags
LEFT JOIN tagmap USING TagID
WHERE RefTable = 'posts' AND RefID = 42Context
StackExchange Code Review Q#26828, answer score: 3
Revisions (0)
No revisions yet.