sql schema tagging

sql - ¿Hay un esquema ideal acordado para etiquetar



schema tagging (7)

Tengo un sitio web con fotos y quiero admitir etiquetas porque mi categoría original está empezando a fallar (algunas fotos son para familias y vacaciones, o para la escuela y amigos). ¿Hay un esquema de etiquetado db de etiquetado?

Todavía quiero apoyar tener fotos como parte de un álbum.

En este momento tengo algunas tablas:

Fotos

  • Identificación fotográfica
  • PhotoAlbumID
  • Subtítulo
  • Fecha

Album de fotos

  • AlbumID
  • AlbumName
  • AlbumDate

Algo como esto viene a mi mente: agrega esas dos tablas

Etiquetas

  • TagID
  • TagName
  • TagDescription

Etiquetas de foto

  • Identificación fotográfica
  • TagID

Puede ampliar esto también a álbumes, teniendo una tabla de intersección entre Álbumes de fotos y Etiquetas.


En mi aplicación BugTracker.NET, hago una suposición de que no habrá demasiados errores. Tal vez decenas de miles, pero no decenas de millones. Esa suposición me permite almacenar en caché las etiquetas y los identificadores de los elementos a los que hacen referencia.

En la base de datos, las etiquetas se almacenan a medida que se ingresan, con los errores, en un campo de texto delimitado por comas.

Cuando se agrega o cambia un campo de etiqueta, se inicia un hilo de fondo que selecciona todos los errores y sus etiquetas, analiza el texto, crea un mapa donde la clave es la etiqueta y el valor es una lista de todos los identificadores que tienen esa etiqueta . Luego guardo en caché ese mapa en el objeto Asp.Net Application.

A continuación está el código que acabo de describir.

El código podría optimizarse para que, en lugar de pasar por todos los errores, simplemente modificara el mapa en caché, pero incluso sin optimizar, funciona bien.

Cuando alguien hace una búsqueda usando una etiqueta, busco el valor en el mapa, obtengo la lista de identificadores y luego obtengo esos errores usando SQL con la cláusula "where id in (1, 2, 3 ...)".

public static void threadproc_tags(object obj) { System.Web.HttpApplicationState app = (System.Web.HttpApplicationState)obj; SortedDictionary<string,List<int>> tags = new SortedDictionary<string,List<int>>(); // update the cache DbUtil dbutil = new DbUtil(); DataSet ds = dbutil.get_dataset("select bg_id, bg_tags from bugs where isnull(bg_tags,'''') <> ''''"); foreach (DataRow dr in ds.Tables[0].Rows) { string[] labels = btnet.Util.split_string_using_commas((string) dr[1]); // for each tag label, build a list of bugids that have that label for (int i = 0; i < labels.Length; i++) { string label = normalize_tag(labels[i]); if (label != "") { if (!tags.ContainsKey(label)) { tags[label] = new List<int>(); } tags[label].Add((int)dr[0]); } } } app["tags"] = tags; }


Lo hice en un sistema pequeño sin muchos usuarios, pero me he preguntado si existía una forma "aceptada" de administrar etiquetas. Después de leer los enlaces publicados por Insin y muchas otras publicaciones de blog sobre etiquetado, parece que la forma aceptada es almacenarlo completamente normalizado y almacenar en caché ciertas cosas si su conjunto de datos se vuelve demasiado grande.

Dado que es una relación de muchos y muchos (cada etiqueta puede pertenecer a cualquier cantidad de fotos, cada foto puede tener muchas etiquetas), la teoría de base de datos relacional hace que crees una tabla de fotos, una tabla de etiquetas y una tabla de referencias cruzadas para vincularlas.

photos photoid caption filename date tags tagid tagname phototags photoid tagid

Esto tiene problemas de escala al seleccionar conjuntos de datos realmente grandes, pero también lo hacen todos los esquemas menos normalizados (la ordenación y el filtrado por un campo de texto probablemente siempre será más lento que el uso de un entero, por ejemplo). Si crece tan grande como delicioso o tal vez incluso , es probable que tenga que hacer un almacenamiento en caché de sus conjuntos de etiquetas.

Otro problema que tendrá que enfrentar es el problema de la normalización de etiquetas. Esto no tiene nada que ver con la normalización de la base de datos, es solo asegurarse de que (por ejemplo) las etiquetas "", "" y "overflow de pila" sean las mismas. Muchos lugares no permiten espacios en blanco o automáticamente lo quitan. A veces verá lo mismo para la puntuación, haciendo que "" sea lo mismo que "Stack-Overflow". Auto-lowercasing es bastante estándar. Incluso verá la normalización de casos especiales, como hacer que "c #" sea lo mismo que "csharp".

Feliz etiquetado!


Sugiero mirar para ver cómo lo hace el software de código abierto establecido. Por ejemplo, Gallery almacena sus metadatos en una base de datos como usted, y es bastante rico.

Sin embargo, no creo que encuentres un esquema "estándar". Lo más parecido que se me ocurre es el formato de metadatos EXIF, que está incrustado en los propios archivos de imagen (por cámaras, etc.).


si desea un rendimiento real con millones de registros, puede almacenar etiquetas en un campo, separados por comas y recuperar registros con un daemon índice / búsqueda de texto completo como sphinxsearch. Todo lo que tiene que agregar es una tabla que enumera todas las etiquetas con un valor de recuento para saber con qué frecuencia están unidas a un elemento.

Sé que no es la manera habitual y un poco más complicada que una solución de base de datos pura, pero es realmente muy rápido para buscar elementos relacionados con etiquetas.

También podría usar la función de búsqueda de texto completo del motor de su base de datos, pero cuando hay muchos registros, la mayoría de los motores tienden a ser lentos.

Si se trata de un proyecto pequeño, puede seguir su camino, las costuras son buenas y adecuadas para hacerlo. Pero solo compartiría contigo esta otra solución. Qué piensas de ?


Una nota rápida sobre cómo manejar las etiquetas:

Los sistemas de etiquetado pueden variar desde etiquetas rígidamente definidas donde crear nuevas requiere trabajo adicional explícito (piense en gmail) hasta sistemas muy laxos donde se recomienda agregar tantas etiquetas como sea posible (piense en flickr o etiquete contenido de audio donde una transcripción se puede aplicar directamente etiquetas).

En general, un medio fácilmente indexable (¡texto!) Debería tener un sistema más rígido, ya que el contenido en sí mismo son las etiquetas; existen etiquetas adicionales más para la categorización solamente. Un medio que es más difícil de indexar (imágenes, video) debe tener un sistema flexible que aliente muchas etiquetas, ya que son su única esperanza al realizar búsquedas.

Esto es importante porque el esquema de la base de datos que desee podría cambiar un poco dependiendo de qué extremo de ese espectro se encuentre.


Existen varios esquemas que son efectivos, cada uno con sus propias implicaciones de rendimiento para las consultas comunes que necesitará a medida que crezca el número de elementos etiquetados:

Personalmente, me gusta tener una tabla de etiquetas y una tabla de enlaces que asocia etiquetas con elementos, ya que está desnormalizado (sin duplicación de nombres de etiquetas) y puedo almacenar información adicional en la tabla de enlaces (como cuando el elemento fue etiquetado) cuando sea necesario.

También puede agregar algunos datos desnormalizados si se siente juguetón y quiere selecciones simples a costa del mantenimiento adicional de datos requerido almacenando conteos de uso en la tabla de etiquetas, o almacenando nombres de etiquetas que se usaron en la tabla de elementos para evitar golpear la tabla de enlace y la tabla de etiquetas para cada elemento, que es útil para mostrar varios elementos con todas sus etiquetas y para el control de versiones simple de etiquetas ... si le gusta ese tipo de cosas;)