一般に、この種の多対多の関係には、3つのテーブルがあります:
- 「
article
"テーブル- 主キー=id
- 「
tag
"テーブル- 主キー=id
- 各タグのデータが含まれています:
- 名前、たとえば
- A "
tags_articles
"テーブル。結合テーブルとして機能し、:- のみが含まれます。
-
id_article
:記事を指す外部キー -
id_tag
:タグを指す外部キー
-
このように、タグのデータが重複することはありません。タグごとに、tag
には1行しかありません。 テーブル。
また、記事ごとに複数のタグを付けることができます(つまり、tags_articles
の複数の行 テーブル);もちろん、タグごとに複数の記事を含めることができます。
このアイデアで記事のタグのリストを取得することは、次のような追加のクエリの問題です:
select tag.*
from tag
inner join tags_articles on tag.id = tags_articles.id_tag
where tags_articles.id_article = 123
3つの「最も類似した」記事を取得するということは、次のことを意味します:
- 最初の記事にタグが付いている記事を選択
- 最も重要な数の同一のタグを持つもののみを使用してください
テストされていませんが、アイデアは次のようになる可能性があります:
select article.id, count(*) as nb_identical_tags
from article
inner join tags_articles on tags_articles.id_article = article.id
inner join tag on tag.id = tags_articles.id_tag
where tag.name in ('php', 'mysql', 'erlang')
and article.id <> 123
group by article.id
order by count(*) desc
limit 3
基本的に、あなたは:
- 最初の記事にある各タグの記事IDを選択します
- 内部結合があるため、DB内の記事に
where
に一致する2つのタグがある場合group by
なしの句 条項、その記事には2行あります - もちろん、すでに持っている記事を再選択する必要はありません。つまり、除外する必要があります。
- 内部結合があるため、DB内の記事に
- ただし、
group by article.id
を使用する場合 、記事ごとに1行のみになります- ただし、
count
を使用することはできます 、各記事に最初の記事と共通するタグの数を確認する
- ただし、
- その後は、タグの数ごとに並べ替えて、3行目だけを取得するだけです。