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)私の2番目の質問は、自分のタグテーブルがint PKを持つべきかどうかです。 TagTitleを主キーとして使用する方が理にかなっていますか?
キャンプには、各テーブルが意味のない連続した整数IDを持つようにしっかりしています。ストレージのスペース(他のテーブルからのFK)を削減し、intルックアップ/レンジマージはvarcharよりも常に高速です。
1cでは 'NOT EXISTS'を使いますhttp://sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/なぜあなたは' UNION ALL 「1bでも?これは 'IN(1,3,8)'ではるかに単純なようです。 –
これはちょっとしたものです。データ配信によっては、他のものよりも速いものが常にあるとは限りません。 NOT EXISTSはおそらく簡潔に読むのが簡単でしょう – RichardTheKiwi
誰かが「SELECT a.ArtID、... FROM記事からINNER JOIN ArticleTags on a.ArtID = at.ArtID INNER JOINタグt ON at.TagID = t.TagID WHERE t.TagTitle = 'tag''? –