私が歌川です

@utgwkk が書いている

トップページには最新N件の記事を出してほしいけどこのタグを持った記事は出さないようにしてほしいな~というときのSQL

スキーマはこちら。型をかなり省略しています。いわゆるToxi法(中間テーブルがある)ってやつです。

create table article (
  id integer primary key,
  ...
);

create table article_tag_rel (
  article_id,
  tag_id,
  ...
);

create table tag (
  id integer primary key,
  name,
  ...
);

どうやって書きますか? 私はこう書きました。

select distinct a.* from article a
left join article_tag_rel atr on a.id = atr.article_id
left join tag t on atr.tag_id = t.id
where t.id is null
or t.name not in ('dame', 'desu', ...)
order by a.id desc limit N;
  • タグがない記事は t.id is null になるので表示される
  • タグがあるならNGタグが付いてないか確認してから表示する

という処理が行われています。記事に対して必ず1個以上のタグがあるならぜんぶ inner join でいい気もする。

SQLだけでやろうとしてこうなっているけど、実用的にはアプリケーションでうまく計算してキャッシュしたりマテリアライズドビュー使ったりするほうがよさそう? このへんどういう実装にすることが多いのか事例を知りたい。

最初はleft joinが3つあったけど、2つでいいじゃんということになった。

参考