¿Cómo diseñar una Tabla MySql para una Nube de Etiquetas?
-
25-09-2019 - |
Pregunta
Tengo artículos en mi sitio y me gustaría agregar etiquetas que describan cada artículo, pero tengo problemas con el diseño de la tabla MySQL para etiquetas.Tengo dos ideas:
- cada artículo tendría un campo "etiquetas" y las etiquetas tendrían el formato:"etiqueta1,etiqueta2,etiqueta3"
- cree otra tabla llamada etiquetas con campos:nombre_etiqueta, id_artículo
Entonces, cuando quiero etiquetas para el artículo con ID 1, ejecuto
SELECT ... FROM tags WHERE `article_id`=1;
Pero también me gustaría conocer los 3 artículos más similares comparando etiquetas, así que si tengo un artículo que tiene etiquetas "php, mysql, erlang" y 5 artículos con etiquetas:"php,mysql", "erlang,ruby", "php erlang", "mysql,erlang,javascript", elegiría 1., 3.y 4., ya que esos 3 tienen la mayoría de las mismas etiquetas que el artículo principal.
También hay otra pregunta: ¿cuál es la mejor manera de obtener las 10 "etiquetas más utilizadas"?
Solución
Generalmente, para este tipo de relación de muchos a muchos, existen tres tablas:
- El "
article
" mesa- clave primaria = identificación
- El "
tag
" mesa- clave primaria = identificación
- contiene los datos de cada etiqueta:
- nombre, por ejemplo
- A "
tags_articles
"tabla, que actúa como una tabla de combinación y contiene solo:id_article
:clave externa que apunta a un artículoid_tag
:clave externa que apunta a una etiqueta
De esta manera, no hay duplicación de datos de ninguna etiqueta:Para cada etiqueta, hay una y sólo una línea en el tag
mesa.
Y, para cada artículo, puedes tener varias etiquetas (es decir,varias líneas en el tags_articles
mesa) ;y, por supuesto, para cada etiqueta, puedes tener varios artículos.
Obtener una lista de etiquetas para un artículo, con esta idea, es cuestión de realizar una consulta adicional, como:
select tag.*
from tag
inner join tags_articles on tag.id = tags_articles.id_tag
where tags_articles.id_article = 123
Obtener los tres artículos "más similares" significaría:
- seleccione artículos que tengan etiquetas que tenga el primer artículo
- Utilice sólo aquellos que tengan el mayor número de etiquetas idénticas.
No probado, pero una idea podría ser algo similar a esto:
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
Básicamente, tú:
- seleccione los identificadores de artículos para cada etiqueta que esté presente en su artículo inicial
- como hay una unión interna, si un artículo en la base de datos tiene 2 etiquetas que coinciden con el
where
cláusula, sin lagroup by
cláusula, habría dos líneas para ese artículo - Por supuesto, no desea volver a seleccionar el artículo que ya tenía, lo que significa que debe excluirse.
- como hay una unión interna, si un artículo en la base de datos tiene 2 etiquetas que coinciden con el
- pero como lo usas
group by article.id
, solo habrá una línea por artículo- pero podrás usar
count
, para saber cuántas etiquetas tiene cada artículo en común con el inicial
- pero podrás usar
- entonces, es sólo cuestión de ordenar por número de etiquetas y obtener solo las terceras tres líneas.
Otros consejos
En primer lugar, tendrá que utilizar la sugerencia de Pascal MARTIN sobre el diseño de la tabla.
En cuanto a encontrar artículos similares, de aquí algo para empezar. Teniendo en cuenta que @article_id es el artículo que desea encontrar coincidencias para, y tag1 @, @ tag2, @ tag3 son las etiquetas para ese artículo:
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í, pero no ha respondido a mi pregunta principal, la forma de obtener 3 artículos más similares?
Respuesta: Sólo tiene que buscar los mismos ID de etiqueta en la tabla resultante de la fusión (tags_articles). Reunirlos y crear un patrón.
Por ejemplo: El artículo 1 tiene etiquetas: 1,2 El artículo 2 tiene etiquetas: 2,3,4 El artículo 5 tiene etiquetas: 6,7,2 Artículo 7 tiene etiquetas: 7,1,2,3
Si desea que los 3 artículos más similares para el artículo 1 que hay que mirar para las etiquetas 1,2. Encontrará el artículo 7, que es más similar y 2 y 5 tienen algunas similitudes.