2008-11-20 7 views
8

Me pregunto si alguien podría proporcionar algún consejo conceptual sobre una forma eficiente de construir un modelo de datos para lograr el sistema simple que se describe a continuación. Soy algo nuevo para pensar de una manera no relacional y quiero intentar evitar cualquier trampa obvia. Tengo entendido que un principio básico es que "el almacenamiento es barato, no se preocupe por la duplicación de datos" como podría hacerlo en un RDBMS normalizado.Asesoramiento de modelado de datos para el sistema de etiquetado de blogs en Google App Engine

Lo que me gustaría es para modelar:

Un artículo de blog que se puede dar 0-n etiquetas. Muchos artículos de blog pueden compartir la misma etiqueta. Al recuperar datos, le gustaría permitir la recuperación de todos los artículos que coinciden con una etiqueta. En muchos sentidos, muy similar al enfoque adoptado aquí en stackoverflow.

Mi mentalidad normal sería crear una relación de muchos a mayos entre las etiquetas y los artículos del blog. Sin embargo, estoy pensando en el contexto de GAE que esto sería costoso, aunque he visto ejemplos de esto.

¿Quizás usando una propiedad de lista que contenga cada etiqueta como parte de las entidades del artículo, y un segundo modelo de datos para seguir las etiquetas a medida que se agregan y eliminan? De esta forma, no hay necesidad de ninguna relación, y ListProperty aún permite consultas en las que cualquier comparación de elemento de lista arrojará resultados.

¿Alguna sugerencia sobre la forma más eficiente de abordar esto en GAE?

Respuesta

7

Gracias a ambos por sus sugerencias. Implementé (primera iteración) de la siguiente manera. No estoy seguro de si es el mejor enfoque, pero está funcionando.

Clase A = Artículos. Tiene una StringListProperty que se puede consultar en sus elementos de lista

Clase B = Etiquetas. Una entidad por etiqueta, también mantiene una cuenta corriente de la cantidad total de artículos que usan cada etiqueta.

Las modificaciones de los datos en A van acompañadas de trabajos de mantenimiento en B. El pensamiento que cuenta que se precalcula es un buen enfoque en un entorno de lectura pesada.

+0

Solo el enfoque que iba a sugerir, excepto que no encontré tiempo. :) –

1

Muchos a muchos suena razonable. Tal vez deberías probarlo primero para ver si realmente es costoso.

Lo bueno de G.A.E. es que te dirá cuándo estás usando demasiados ciclos. ¡Perfilando gratis!

+0

estaba pensando muchos-a-muchos demasiado pero incluso la documentación en Google advierte contra esta en todo menos en las situaciones más necesarias. Un buen consejo sobre el perfil, creo que intentaré ejecutar algunas pruebas utilizando diferentes enfoques e informar los resultados aquí. – Matty

1

Una forma posible es con Expando, donde deberá añadir una etiqueta como:

setattr(entity, 'tag_'+tag_name, True) 

Posteriormente, se podría consultar todas las entidades con una etiqueta como:

def get_all_with_tag(model_class, tag): 
    return model_class.all().filter('tag_%s =' % tag, True) 

Por supuesto que tienes para limpiar sus etiquetas para que sean los identificadores de Python adecuados. No lo he intentado, así que no estoy seguro de si realmente es una buena solución.

+1

¿Qué pasa si los nombres de las etiquetas no tienen que ser en inglés? –

2

recuentos de ser pre-calculado es no sólo práctico , sino también necesario porque la función count() devuelve un máximo de 1000 . si la contención de escritura puede ser un problema, asegúrese de verificar el ejemplo del contador fragmentado.

http://code.google.com/appengine/articles/sharding_counters.html

+0

En las versiones más recientes de gae sdk, la función count() no tiene límite máximo: http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query_count –

+0

true! editará – mainsocial

Cuestiones relacionadas