2008-11-20 4 views
8

Je me demande si quelqu'un pourrait fournir des conseils conceptuels sur un moyen efficace de créer un modèle de données pour accomplir le système simple décrit ci-dessous. Suis un peu nouveau à penser d'une manière non relationnelle et je veux essayer d'éviter les pièges évidents. Je crois comprendre qu'un principe de base est que «le stockage est bon marché, ne vous inquiétez pas de la duplication de données» comme vous le feriez dans un SGBDR normalisé.Conseils sur la modélisation des données pour le système de balisage de blog sur Google App Engine

Ce que je voudrais modèle est:

Un article de blog qui peut être donné des balises 0-n. De nombreux articles de blog peuvent partager le même tag. Lorsque vous récupérez des données, vous souhaitez pouvoir récupérer tous les articles correspondant à une étiquette. De beaucoup de manières très semblables à l'approche prise ici chez stackoverflow.

Mon état d'esprit normal serait de créer une relation many-to-may entre les balises et les articles de blog. Cependant, je pense dans le contexte de la GAE que cela coûterait cher, même si j'en ai vu des exemples. Peut-être utiliser un ListProperty contenant chaque tag dans le cadre des entités article, et un second modèle de données pour suivre les tags au fur et à mesure qu'ils sont ajoutés et supprimés? De cette façon, pas besoin de relations et le ListProperty permet toujours des requêtes où tout élément de la liste correspondant retournera les résultats.

Des suggestions sur la manière la plus efficace d'aborder cela sur GAE?

Répondre

7

Merci à vous deux pour vos suggestions. J'ai implémenté (première itération) comme suit. Je ne sais pas si c'est la meilleure approche, mais ça marche.

Classe A = Articles. A une propriété StringListProperty qui peut être interrogée sur ses éléments de liste

Classe B = Balises. Une entité par étiquette conserve également un compte courant du nombre total d'articles utilisant chaque étiquette.

Les modifications de données de A sont accompagnées de travaux de maintenance sur B. Penser que le compte est pré-calculé est une bonne approche dans un environnement de lecture-lourde.

+0

Juste l'approche que j'allais suggérer, sauf que je n'ai pas trouvé le temps. :) –

1

Plusieurs-à-plusieurs sons raisonnables. Peut-être devriez-vous essayer d'abord si c'est vraiment cher.

Bonne chose à propos de G.A.E. c'est qu'il vous dira quand vous utilisez trop de cycles. Profilage gratuit!

+0

Je pensais beaucoup à beaucoup trop mais même la documentation à Google met en garde contre ce sauf dans les situations les plus nécessaires. De bons conseils sur le profilage, je pense que je vais essayer de faire des tests en utilisant différentes approches et de rapporter les résultats ici. – Matty

1

Une façon possible est avec Expando, où vous souhaitez ajouter un tag comme:

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

Ensuite, vous pouvez interroger toutes les entités avec une étiquette comme:

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

Bien sûr, vous avez nettoyer vos tags pour qu'ils soient des identifiants Python corrects. Je n'ai pas essayé cela, donc je ne suis pas sûr que ce soit vraiment une bonne solution.

+1

Et si les noms de balise ne doivent pas être anglais? –

2

nombre pré-calculé est non seulement pratique , mais également nécessaire car la fonction count() renvoie un maximum de 1000 . Si le conflit d'écriture peut être un problème, assurez-vous de vérifier l'exemple du compteur sharded.

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

+0

Dans les dernières versions de Gae sdk la fonction count() n'a pas de limite maximale: http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query_count –

+0

vrai! éditera. – mainsocial

Questions connexes