Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como projetar uma tabela MySql para uma nuvem de tags?


Geralmente, para esse tipo de relacionamento muitos-para-muitos, existem três tabelas:
  • O "article " mesa
    • chave primária =código
  • A "tag " mesa
    • chave primária =código
    • contém os dados de cada tag:
      • nome, por exemplo
  • Um "tags_articles " table, que atua como uma tabela de junção e contém apenas :
    • id_article :chave estrangeira que aponta para um artigo
    • id_tag :chave estrangeira que aponta para uma tag


Dessa forma, não há duplicação de dados de nenhuma tag:para cada tag, há uma, e apenas uma, linha na tag tabela.

E, para cada artigo, você pode ter várias tags (ou seja, várias linhas no tags_articles tabela); e, claro, para cada tag, você pode ter vários artigos.

Obter uma lista de tags para um artigo, com essa ideia, é uma questão de consulta adicional, como:
select tag.*
from tag
    inner join tags_articles on tag.id = tags_articles.id_tag
where tags_articles.id_article = 123


Receber os três artigos "mais semelhantes" significaria:
  • selecione artigos que tenham tags que o primeiro artigo tem
  • use apenas aqueles que têm o número mais importante de tags idênticas

Não testado, mas uma ideia pode ser algo parecido com isto:
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

Basicamente, você:
  • selecione os IDs dos artigos para cada tag presente em seu artigo inicial
    • como há uma junção interna, se um artigo no banco de dados tiver 2 tags que correspondam ao where cláusula, sem o group by cláusula, haveria duas linhas para esse artigo
    • claro, você não deseja selecionar novamente o artigo que já possuía -- o que significa que ele deve ser excluído.
  • mas, como você usa group by article.id , haverá apenas uma linha por artigo
    • mas você poderá usar count , para descobrir quantas tags cada artigo tem em comum com o inicial
  • então, é apenas uma questão de classificar por número de tags e obter apenas as três terceiras linhas.