2008-10-05 10 views
16

Tengo un sitio web de 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?¿Hay un esquema ideal acordado para etiquetar

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

Ahora mismo tengo unas pocas mesas:

Fotos

  • photoid
  • PhotoAlbumID
  • Leyenda
  • Fecha

Álbum de Fotos

  • ALBUMID
  • ALBUMNAME
  • AlbumDate

Respuesta

21

Hay varios esquemas que son eficaces, cada uno con sus propias implicaciones rendimiento de las consultas más comunes que necesitará como el número de artículos etiquetados crece:

Personalmente, me gusta tener una tabla de variables y una mesa de enlace que asocia las etiquetas con los objetos, ya que está desnormalizará (sin duplicación de nombres de etiqueta) y puedo almacenar información adicional en la tabla de enlace (tales como cuando el artículo fue etiquetado) cuando sea necesario.

También puede agregar algunos datos desnormalizados si se siente juguetón y desea selecciones simples a costa del mantenimiento adicional de datos requerido almacenando recuentos de uso en la tabla de etiquetas o almacenando nombres de etiquetas que se usaron en la tabla de artículos para evitar golpear la tabla de enlaces y la tabla de etiquetas para cada elemento, lo que es útil para mostrar varios elementos con todas sus etiquetas y para el control de versiones simple de etiquetas ...si usted está en ese tipo de cosas;)

2

Algo como esto viene a la mente: agregar esas dos tablas

Etiquetas

  • TagID
  • TagName
  • TagDescription

PhotoTags

  • photoid
  • TagID

Puede extender esto a álbumes también, tener una tabla de intersección entre los álbumes de fotos y etiquetas.

+0

cómo evitar personas que no usan el mismo nombre para una etiqueta (como sensibilidades de casos, etc.) – leora

+0

@akantro: proporcióneles una lista de etiquetas para animarlas a elegir una en lugar de escribir una nueva. O el equivalente moderno, un cuadro de texto con finalización de etiqueta impulsada por AJAX. –

+0

¿existe un control preconstruido para la finalización de la etiqueta impulsada por AJAX? – leora

2

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.

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.).

0

si desea un rendimiento real con millones de registros, puede almacenar etiquetas en un campo, separar por comas y recuperar registros con un daemon de í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 forma 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 las etiquetas.

Puede usar también la funcionalidad 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 ?

10

He hecho esto en un sistema pequeño sin muchos usuarios, pero me he preguntado antes 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 (cada etiqueta puede pertenecer a cualquier número de fotos, cada foto puede tener muchas etiquetas), la teoría de base de datos relacional crea una tabla de fotos, una tabla de etiquetas y una tabla de referencias cruzadas vincularlos.

photos 
    photoid 
    caption 
    filename 
    date 

tags 
    tagid 
    tagname 

phototags 
    photoid 
    tagid 

Esto ha escalado problemas de selección de conjuntos de datos muy grandes, pero también lo hacen todos los esquemas menos normalizados (clasificación y filtrado por un campo de texto probablemente siempre será más lento que el uso de un número entero, por ejemplo). Si crece tan grande como delicioso o tal vez incluso StackOverflow, 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 "StackOverflow", "stackoverflow" 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 "StackOverflow" 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".

Happy tagging!

+0

¿cuál es la mejor respuesta para la normalización de etiquetas? – leora

+1

Creo que dependería mucho de lo que estás etiquetando. Sin embargo, prefiero una gran normalización: realmente quieres mantener bajo el número de etiquetas. – Neall

0

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 tiene esa etiqueta. Luego guardo en caché ese mapa en el objeto Asp.Net Application.

A continuación se muestra el código que acabo de describir.

El código podría optimizarse para que en lugar de pasar por todos los errores modificara gradualmente 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 "where id in (1, 2, 3 ...) "cláusula.

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; 

    } 
+0

por qué no lo normaliza. . – leora

+0

La normalización sería más lenta para lecturas, inserciones y actualizaciones. y elimina Por qué * ¿HARÍA * normalizar? Más importante aún, independientemente de cómo se almacenan físicamente los datos de la etiqueta, cuando realmente los utilizo para las búsquedas, estoy usando lo que está en la memoria caché. El esquema db en sí mismo es realmente irrelevante en el momento de la búsqueda. –

0

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

sistemas de etiquetado pueden variar de etiquetas muy rígidamente definidos, donde la creación de otras nuevas requieren un trabajo extra explícita (piensan Gmail) para sistemas muy sueltos, donde la adición de tantas etiquetas como sea posible se recomienda (piense en flickr, o etiquete contenido de audio donde una transcripción se puede aplicar directamente como etiquetas).

En general, un medio fácilmente indexable (texto!) Debería tener un sistema más rígido, ya que el contenido en sí son existen las etiquetas adicionales etiquetas-más por sólo categorización. 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 desea puede cambiar un poco dependiendo de qué extremo de ese espectro se encuentre.

Cuestiones relacionadas