2010-05-21 12 views
23

Relatedformas de implementar las etiquetas - pros y los contras de cada

Uso de SO como un ejemplo, ¿cuál es la manera más sensata para gestionar etiquetas si prevé que va a cambiar con frecuencia?

Camino 1: En serio desnormalizado (delimitado por comas)

 
table posts 
+--------+-----------------+ 
| postId | tags   | 
+--------+-----------------+ 
| 1 | c++,search,code | 

Aquí etiquetas están delimitadas por comas.

Pros: Las etiquetas se recuperan a la vez con una sola consulta select. La actualización de etiquetas es simple. Fácil y económico de actualizar.

Contras: Análisis adicional en la recuperación de etiquetas, es difícil contar cuántas publicaciones usan qué etiquetas.

(alternativamente, si se limita a algo así como 5 etiquetas)

 
table posts 
+--------+-------+-------+-------+-------+-------+ 
| postId | tag_1 | tag_2 | tag_3 | tag_4 | tag_5 | 
+--------+-------+-------+-------+-------+-------+ 
| 1 | c++ |search | code |  |  | 

manera 2: (tabla separada, sin intersección) "Un poco normalizada"

 
table posts 
+--------+-------------------+ 
| postId | title    | 
+--------+-------------------+ 
| 1 | How do u tag?  | 

table taggings 
+--------+---------+ 
| postId | tagName | 
+--------+---------+ 
| 1 | C++  | 
| 1 | search | 

Pros: Fácil de ver conteo de etiquetas (count(*) from taggings where tagName='C++').

Contras: tagName probablemente se repita muchas, muchas veces.

Vía 3: El niño fresco (normalizada con tabla de intersección)

 
table posts 
+--------+---------------------------------------+ 
| postId | title         | 
+--------+---------------------------------------+ 
| 1 | Why is a raven like a writing desk? | 

table tags 
+--------+---------+ 
| tagId | tagName | 
+--------+---------+ 
| 1 | C++  | 
| 2 | search | 
| 3 | foofle | 

table taggings 
+--------+---------+ 
| postId | tagId | 
+--------+---------+ 
| 1 | 1  | 
| 1 | 2  | 
| 1 | 3  | 

Pros:

  • No se repiten los nombres de etiqueta.
  • Más chicas te gustarán.

Contras: Más caro para cambiar las etiquetas que la forma # 1.

+0

Enviaría un correo electrónico/twitter a alguien que haya tenido que administrar etiquetas antes que usted. Le gusta Jeff Atwood o uno de los otros desarrolladores de SO. Es posible que puedan dar algunas ideas. –

+6

me parece que acabas de responder la pregunta. Por lo tanto, elija la que mejor se adapte a sus necesidades. Si quieres que las chicas te gusten, entonces ve al # 3. – mdma

+0

Más chicas te querrán, ¿eh? Me gusta esa elección! – Tarka

Respuesta

23

Estas soluciones se llaman mysqlicious, scuttle y toxi.

This article compara los beneficios y desventajas de cada uno.

+0

Ah sí, acabo de encontrar esto. ¡Muy útil! – bobobobo

+0

Parece que el enlace está roto. – Diederik

+0

@Diederik: vea ahora – Quassnoi

0

Personalmente prefiero la solución n. ° 3.

No estoy de acuerdo con que la solución # 1 sea más fácil de mantener. Piensa en la situación en la que tienes que cambiar el nombre de una etiqueta.

Solución # 1:

UPDATE posts SET tag = REPLACE(tag, "oldname", "newname") WHERE tag LIKE("%oldname%") 

Solución # 3:

UPDATE tags SET tag = "newname" WHERE tag = "oldname" 

La primera de ellas es la forma más pesado.

también tiene que lidiar con las comas cuando se eliminan las etiquetas (Ok, es fácil de hacer, pero aún así, más difícil que acaba de borrar una línea en la tabla taggings)

En cuanto a la solución # 2 ... no es ni carne ni pescado

1

yo diría que hay una cuarta solución que es una variación en su tercera solución:

Create Table Posts 
(
    id ... 
    , title ... 
) 
Create Table Tags 
(
    name varchar(30) not null primary key 
    , ... 
) 

Create Table PostTags 
(
    PostId ... 
    , TagName varchar(30) not null 
    , Constraint FK_PostTags_Posts 
     Foreign Key (PostId) 
     References Posts(Id) 
    , Constraint FK_PostTags_Tags 
     Foreign Key (TagName) 
     References Tags(Name) 
     On Update Cascade 
     On Delete Cascade 
) 

en cuenta que estoy usando el nombre de la etiqueta como la clave principal de la tabla de etiquetas. De esta forma, puede filtrar ciertas etiquetas sin la unión adicional a la tabla de etiquetas en sí. Además, si cambia un nombre de etiqueta, actualizará los nombres en la tabla Etiquetas postales. Si cambiar el nombre de una etiqueta es una ocurrencia rara, entonces esto no debería ser un problema. Si cambiar el nombre de una etiqueta es una ocurrencia común, entonces iría con su tercera solución donde use una clave sustituta para hacer referencia a la etiqueta.

+0

@Thomas: esto es lo mismo que 'scuttle', solo que es mucho más difícil de administrar. Posibilidad de escribir 'UPDATE Tags SET TagName = 'newtag' WHERE TagName = 'oldtag'' en lugar de' UPDATE PostTags SET TagName =' newtag 'DONDE TagName =' oldtag'' realmente no lo vale. – Quassnoi

+0

@Quassnoi - Con Cascade Update solo necesita escribir 'Update Tags Set Name = 'NewName' Donde Name = 'OldName''. No es más difícil de gestionar que si usa una clave sustituta. La verdadera pregunta es si el beneficio de evitar la unión extra supera la frecuencia con la que está alterando un nombre de etiqueta existente. Como supondría que el último es poco frecuente, el beneficio de rendimiento probablemente valga la pena. – Thomas

+0

@Thomas: de nuevo, ¿cómo es diferente de la forma 2 ('scuttle') excepto que tiene una tabla adicional (' Tags') que no sirve para nada? – Quassnoi

0

Creo que SO usa la solución n. ° 1. Me gustaría ir con # 1 o # 3.

Una cosa a considerar es si tiene varias cosas que puede etiquetar (por ejemplo, agregar etiquetas a publicaciones y productos, por ejemplo). Esto puede afectar la solución de la base de datos.

0

Bueno, tengo la misma duda. Adopté la tercera solución para mi sitio web. Sé que hay otra manera de lidiar con este problema de las tuplas de longitud variable, que consiste en utilizar columnas como filas, de esta manera tendrá alguna información que identifique la tupla redudant y las variadas organizadas para cada fila.

+--------+-------+-------------------------------------+ 
| postId | label | value        | 
+--------+-------+-------------------------------------+ 
| 1 | tag |C++         | 
+--------+-------+-------------------------------------+ 
| 1 | tag |search        | 
+--------+-------+-------------------------------------+ 
| 1 | tag |code         | 
+--------+-------+-------------------------------------+ 
| 1 | title | Why is a raven like a writing desk? | 
+--------+-------+-------------------------------------+ 

Esto es muy malo, pero a veces es la única solución viable, y es muy lejos del enfoque relacional.

+0

y sin embargo es bastante fácil de actualizar y mantener, las consultas se ralentizan pero es posible que tenga el mismo problema de tiempo al unir un gran número de tuplas de 3 tablas diferentes, puede considerar usar diferentes índices para aumentar el rendimiento de ciertos tipos de consultas. Espero que esto haya ayudado – urobo

Cuestiones relacionadas