1a) Мой первый вопрос: как лучше написать запрос, чтобы найти все статьи, связанные с данным тегом?
select ArtID -- if only IDs are required
from ArticleTags
where TagID=1 -- or use the text (where tagtitle='x')
select A.*
from ArticleTags T inner join Articles A on A.ArtID = T.ArtID
where T.TagID=1
1b) В реальной жизни мне нужно будет найти статьи с несколькими тегами
-- has tags 1,3 and 8
select T1.ArtID
from ArticleTags T1
inner join ArticleTags T2 on T1.ArtID = T2.ArtID and T2.TagID = 3
inner join ArticleTags T3 on T1.ArtID = T3.ArtID and T3.TagID = 8
where T1.TagID=1
-- or use the text (tagtitle='x') on each filter
В некоторых случаях эта форма работает быстрее. К этому или предыдущему можно присоединиться, чтобы получить записи статьи.
select ArtID
from (
select T1.ArtID from ArticleTags T1 where T1.TagID=1
union all
select T2.ArtID from ArticleTags T2 where T2.TagID=3
union all
select T3.ArtID from ArticleTags T3 where T3.TagID=8
) X
group by ArtID
having count(ArtID) = 3
1c) и было бы неплохо также найти статьи, которые НЕ связаны с определенным тегом.
select A.*
from Articles A
left join ArticleTags T on T.ArtID = A.ArtID and T.TagTitle = 'nomatch'
where T.ArtID is null
2) Мой второй вопрос о том, должна ли моя таблица тегов иметь int PK? Имеет ли смысл использовать TagTitle в качестве первичного ключа?
Я твердо в лагере, который говорит, что каждая таблица должна иметь последовательный, бессмысленный целочисленный идентификатор. Это сокращает пространство хранения (FK из других таблиц), а поиск в диапазоне / поиск по диапазону всегда быстрее, чем varchar.