2011-05-30 5 views
2

Mes antécédents sont dans les bases de données relationnelles et je fais des expériences avec Google AppEngine principalement pour l'apprentissage. Je veux construire une application "élection" où un utilisateur appartient à un état (CA, NY, TX, etc), ils choisissent une partie (républicaine, démocratique, etc) et votent pour une année donnée (2012 pour l'instant mais l'application pourrait être réutilisée en 2016).Google AppEngine Sharding Question

Je veux qu'un utilisateur puisse voir son historique de vote et le changer une fois pour l'élection en cours. En outre, je vais exiger que les utilisateurs spécifient leur code postal et pensent qu'il serait bon d'exécuter des rapports par état et/ou code postal.

L'utilisation d'un DB relationnelle, il semble que vous voulez créer des tables comme ceci:

Users(userid, username, city, state, zip) 
UserVote(userid, year, vote) 

Et puis utilisez SQL pour exécuter des rapports. Avec le magasin de données AppEngine, il semble que l'exécution de rapports agrégés constitue un véritable défi.

Ma première prise serait de partitionner par User où chaque utilisateur peut contenir une liste de Votes et peut-être en double-enregistrer les agrégats ailleurs.

Des suggestions?

P.S. J'ai vu le projet AppEngine-MapReduce, mais je ne suis pas sûr si ce serait exagéré.

+0

Qu'entendez-vous par «partition par utilisateur»? Pourquoi Mapreduce est-il exagéré? –

+0

En ce qui concerne la «partition par utilisateur» - à partir de ma connaissance limitée du magasin de données, il n'y a aucun moyen de se joindre à travers les entités, sauf s'il s'agit d'une relation hiérarchique. La sélection minutieuse des entités "racine" (c'est-à-dire des utilisateurs) vous permet d'interroger par entité associée. En ce qui concerne mapreduce étant surpuissant - il semble que ce soit un moyen de calculer des agrégats, mais ajoute une couche supplémentaire de complexité en plus de beaucoup d'autres choses que j'essaie d'apprendre. – dana

Répondre

1

Je ne me souviens pas exactement où j'ai lu ceci, mais les propriétés de liste dans GAE deviennent lentes après avoir atteint environ 200 éléments. Je recommanderais contre cela en faveur de l'approche par clé étrangère pour les utilisateurs et les votes.

Les agrégats sont un défi car il n'y a aucune des fonctions auxiliaires communes telles que MAX, SUM, COUNT et ainsi de suite. La meilleure approche consiste à stocker des agrégats et des comptes dans un type de données distinct que vous pouvez facilement interroger et mettre à jour à chaque fois qu'un utilisateur vote. Il est plus facile pour AppEngine de passer du temps lorsque vous écrivez afin d'avoir des requêtes plus rapides plus tard.

Voici un exemple des objets en Java:

@PersistenceCapable 
public class User{ 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Key key; 
    ... 
} 

@PersistenceCapable 
public class Vote{ 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Key key; 

    @Persistent 
    private Key userKey; // References a User 
    ... 
} 

@PersistenceCapable 
public class UserStats{ 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Key key; 

    @Persistent 
    private Key userKey; // References a User 
    ... 
} 

En outre, sharding traditionnelle ne fait pas beaucoup de sens dans AppEngine depuis le datastore sous-jacent est conçu pour traiter les requêtes sur des ensembles de données massifs avec facilité. L'exception est si vous avez un compteur spécifique qui peut être modifié fréquemment et qui a le potentiel pour plusieurs utilisateurs de le changer en même temps. C'est un type de sharding différent de celui auquel vous êtes habitué dans MySQL. Voici l'article de Google sur les compteurs de fragmentation: http://code.google.com/appengine/articles/sharding_counters.html

+0

Merci pour les conseils! Malheureusement, je pense que cela pourrait être un scénario où plusieurs utilisateurs pourraient mettre à jour le même compteur en même temps :((2 utilisateurs du même état passant un vote) Je pense que cela pourrait valoir la peine de vérifier le projet mapreduce après tout , mais j'aime votre suggestion de séparer le 'User' du' Vote' du 'Stats'. – dana

+0

vous voudriez partitionner le compteur pour un exemple voir http://code.google.com/p/google-app -expert-moteur/source/browse/trunk/sharded-counters/generalcounter.py –