2

Disons que je veux afficher une liste de livres et leurs auteurs. Dans la conception de base de données traditionnelle, j'émettais une seule requête pour récupérer les lignes de la table Book ainsi que la table Author associée, une étape connue sous le nom désirant aller chercher. Ceci est fait pour éviter le redouté N + 1 sélectionnez le problème: Si les enregistrements Author ont été récupérés paresseusement, mon programme devrait émettre une requête distincte pour chaque auteur, peut-être autant de requêtes qu'il y a de livres dans la liste. Le magasin de données Google App Engine fournit-il un mécanisme similaire ou le problème de sélection N + 1 est-il quelque chose qui n'est plus pertinent sur cette plate-forme?Est-ce que GAE Datastore prend en charge la récupération ardue?

Répondre

3

Je pense que vous demandez implicitement si Google App Engine prend en charge JOIN pour éviter le problème de sélection N + 1.
Google App Engine ne prend pas en charge JOIN directement mais vous permet de définir un one to many relationship en utilisant ReferenceProperty.

class Author(db.Model): 
    name = db.StringProperty() 

class Book(db.Model): 
    title = db.StringProperty() 
    author= db.ReferenceProperty(Author) 

Dans vous scénario spécifique, avec deux appels de requête, le premier à obtenir l'auteur:

author = Author.all.filter('name =' , 'fooauthor').get() 

et le second pour trouver tous les livres d'un auteur donné:

books = Book.all().filter('author=', author).fetch(...) 

vous pouvez obtenir le même résultat d'une requête SQL commune qui utilise JOIN.

Le N + 1 problème pourrait par exemple apparaître lorsque l'on veut obtenir 100 livres, chacun avec son nom de l'auteur:

books = Book.all().fetch(100) 
for book in books: 
    print book.author.name 

Dans ce cas, nous avons besoin d'exécuter 1 + 100 requêtes, un pour obtenir la liste des livres et 100 pour déréférencer tous les objets auteurs pour obtenir le nom de l'auteur (cette étape est implicitement effectuée sur l'instruction book.author.name).

Une technique commune pour résoudre ce problème est à l'aide get_value_for_datastore méthode qui récupère la clé de l'auteur fait référence d'un livre donné sans déréférencement (ie, un datastore fetch):

author_key = Book.author.get_value_for_datastore(book) 

Il y a un blog post brillant sur ce sujet que vous pourriez vouloir lire.
Cette méthode, à partir de la liste author_key, prélève les objets auteurs de la banque de données en définissant chacun d'eux dans le livre d'entités approprié.
Cette approche permet d'économiser beaucoup d'appels à la banque de données et pratiquement * évite le problème N + 1.

* théoriquement, sur une étagère avec 100 livres écrits par 100 auteurs différents, nous avons encore appeler le magasin de données 100 + 1 fois

répondre à votre question:

  • Google App Engine fait ne supporte pas aller chercher
  • désireux
  • Il existe des techniques (pas de la boîte) qui permet d'éviter la redoutée N + 1 problème
+0

Très bien, merci! Y a-t-il un 'ReferenceProperty' pour Java? –

+0

@Jen jeter un oeil [ici] (http://code.google.com/intl/it-IT/appengine/docs/java/datastore/relationships.html#Owned_One_to_Many_Relationships) – systempuntoout

Questions connexes