Domanda

Ho articoli sul mio sito, e vorrei aggiungere tag che descrivono ogni articolo, ma sto avendo problemi con la tabella dati mysql per i tag. Ho due idee:

  1. ogni articolo avrebbe campo "tag" e tag sarebbe in formato: "tag1, tag2, tag3"
  2. creare altri tag table chiamato con i campi: tag_name, article_id

Così, quando voglio tag per articolo con ID 1, vorrei correre

SELECT ... FROM tags WHERE `article_id`=1;

Ma, mi piace anche sapere 3 articoli più simili confrontando i tag, quindi se ho un articolo che ha tag "php, mysql, Erlang", e 5 articoli con tag: "php, mysql", "Erlang, ruby", "php Erlang", "mysql, Erlang, javascript", sceglierei 1., 3. e 4., dal momento che coloro che hanno la maggior parte 3 stessi tag con l'articolo principale.

Inoltre altra domanda, qual è il modo migliore per ottenere 10 "Tag più usate"?

È stato utile?

Soluzione

In generale, per questo tipo di molti-a-molti, ci sono tre tabelle:

  • La tabella "article"
    • chiave primaria = id
  • La tabella "tag"
    • chiave primaria = id
    • contiene i dati di ogni tag:
      • nome, ad esempio
  • Una tabella "tags_articles", che agisce come un join tavolo, e contiene solo:
    • id_article: chiave esterna che punta a un articolo
    • id_tag: chiave esterna che punta a un tag


In questo modo, non v'è alcuna duplicazione dei dati di ogni tag:. Per ogni tag, ce n'è uno, e solo uno, riga nella tabella tag

E, per ogni articolo, è possibile avere diversi tag (cioè diverse righe della tabella tags_articles); e, naturalmente, per ogni tag, è possibile avere diversi articoli.

Ottenere un elenco di tag per un articolo, con questa idea, è una questione di una query additionnal, come:

select tag.*
from tag
    inner join tags_articles on tag.id = tags_articles.id_tag
where tags_articles.id_article = 123


Ottenere i tre "la maggior parte degli articoli simili" significherebbe:

  • selezionare gli articoli che hanno tag che il primo articolo ha
  • utilizzare solo quelle che hanno il maggior numero importante di tag identiche

Non testato, ma un'idea potrebbe essere qualcosa che sarebbe simile a questa:

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

In sostanza, è:

  • selezionare gli articoli ID per ogni tag che è presente sul vostro articolo iniziale
    • in quanto v'è un inner join, se un articolo del DB ha 2 tag che corrispondono alla clausola where, senza la clausola group by, ci sarebbero due linee per questo articolo
    • , naturalmente, non si vuole riselezionare l'articolo che hai già avuto -. Che significa che deve essere esclusa
  • , ma, come si usa group by article.id, ci sarà solo una riga per ogni articolo
    • , ma sarete in grado di utilizzare count, per scoprire quanti tag ogni articolo ha in comune con quella iniziale
  • allora, è solo una questione di selezione per numero di tag, e ottenendo solo il terzo tre linee.

Altri suggerimenti

Prima di tutto, ti consigliamo di utilizzare il suggerimento di Pascal MARTIN circa la struttura della tabella.

Per quanto riguarda la ricerca di articoli simili, di qui qualcosa per iniziare. Dato che @article_id è l'articolo che si desidera trovare corrispondenze per e @ tag1, @ tag2, @ tag3 sono i tag per questo articolo:

SELECT article_id, count(*)
FROM tags_articles
WHERE article_id <> @article_id
AND tag_id IN (@tag1, @tag2, @tag3)
GROUP BY article_id
ORDER BY count(*) DESC
LIMIT 3

Sì, ma non hai risposto alla mia domanda principale, come ottenere 3 articoli più simili?

Risposta: Basta guardare per gli stessi ID di tag nella tabella risultante dalla fusione (tags_articles). raccoglierle e creare un modello.

Ad esempio: Articolo 1 ha tags: 1,2 Articolo 2 ha tags: 2,3,4 Articolo 5 ha tags: 6,7,2 Articolo 7 ha tags: 7,1,2,3

Se si desidera che i 3 articoli più simile per l'articolo 1, si deve guardare per i tag 1,2. Troverete l'articolo 7, che è più simile e 2 e 5 hanno alcune somiglianze.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top