Sorry if the title is not clear - feel free to improve.
Here are 3 tables (not all data is relevant to the question):
CREATE TABLE `content` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`community_id` int(10) unsigned NOT NULL COMMENT 'The community for whom this URL has special rules',
`url_id` int(10) unsigned DEFAULT NULL COMMENT 'The URL that has special rules',
`question_id` int(10) unsigned DEFAULT NULL,
`banned` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Flags if a URL is banned from the community',
`featured` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'If this article is to be featured on this site',
`slider_image` tinytext,
`weight` int(11) DEFAULT '0',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `content_url_unique` (`community_id`,`url_id`),
UNIQUE KEY `content_question_unique` (`community_id`,`question_id`),
KEY `community_index` (`community_id`),
KEY `content_url_idx` (`url_id`),
KEY `content_community_idx` (`community_id`),
KEY `content_question_idx` (`question_id`),
CONSTRAINT `content_community` FOREIGN KEY (`community_id`) REFERENCES `community` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `content_question` FOREIGN KEY (`question_id`) REFERENCES `question` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `content_url` FOREIGN KEY (`url_id`) REFERENCES `url` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=186 DEFAULT CHARSET=utf8;
CREATE TABLE `url_tag` (
`url_id` int(10) unsigned NOT NULL COMMENT 'The URL to be tagged',
`tag_id` int(10) unsigned NOT NULL COMMENT 'The tag the url refers to',
PRIMARY KEY (`url_id`,`tag_id`),
KEY `FK_urltag_url_idx` (`url_id`),
KEY `FK_urltag_tag_idx` (`tag_id`),
CONSTRAINT `FK_urltag_tag` FOREIGN KEY (`tag_id`) REFERENCES `tag` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `FK_urltag_url` FOREIGN KEY (`url_id`) REFERENCES `url` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Allows to tag URLs';
CREATE TABLE `question_tag` (
`question_id` int(10) unsigned NOT NULL,
`tag_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`question_id`,`tag_id`),
UNIQUE KEY `question_tag` (`question_id`,`tag_id`),
KEY `fk_questiontag_question_idx` (`question_id`),
KEY `fk_questiontag_tag_idx` (`tag_id`),
CONSTRAINT `fk_questiontag_question` FOREIGN KEY (`question_id`) REFERENCES `question` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `fk_questiontag_tag` FOREIGN KEY (`tag_id`) REFERENCES `tag` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='The tags associated with a given question';
Note that Content is meant to have either a url_id, or a question_id - not both.
I need a way to connect a Content ID to a Tag ID. I was thinking of creating a VIEW, and here are 2 possibilities I came up with so far.
Option 1:
(SELECT content.id AS content_id, url_tag.tag_id AS tag_id
FROM url_tag, content
WHERE url_tag.url_id = content.url_id)
UNION
(SELECT content.id AS content_id, question_tag.tag_id AS tag_id
FROM question_tag, content
WHERE question_tag.question_id = content.question_id)
Option 2:
SELECT content.id AS content_id, COALESCE(url_tag.tag_id, question_tag.tag_id) AS tag_id
FROM `content`
LEFT JOIN url_tag ON content.url_id = url_tag.url_id
LEFT JOIN question_tag ON content.question_id = question_tag.question_id WHERE COALESCE(url_tag.tag_id, question_tag.tag_id) IS NOT NULL
My question is which one is the better approach (or if there is one better)?
Note also that currently some Contents are not tagged at all.
Bonus challenge: a VIEW that connects content_id straight to category_id
CREATE TABLE `category_tag` (
`category_id` int(10) unsigned NOT NULL,
`tag_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`category_id`,`tag_id`),
KEY `FK_categorytag_category_idx` (`category_id`),
KEY `FK_categorytag_tag_idx` (`tag_id`),
CONSTRAINT `FK_categorytag_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `FK_categorytag_tag` FOREIGN KEY (`tag_id`) REFERENCES `tag` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;