开发者

Does GAE Datastore support eager fetching?

Let's say I want to display a list of books and their authors. In traditional database design, I would issue a single query to retrieve rows from the Book table as well as the related Author table, a step known as eager fetching. This is done to avoid the dreaded N+1 select problem: If the Author records were retrieved lazily, my program would have to issue a separate query for each aut开发者_Go百科hor, possibly as many queries as there are books in the list.

Does Google App Engine Datastore provide a similar mechanism, or is the N+1 select problem something that is no longer relevant on this platform?


I think you are implicitly asking if Google App Engine supports JOIN to avoid the N+1 select problem.
Google App Engine does not support JOIN directly but lets you define a one to many relationship using ReferenceProperty.

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

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

In you specific scenario, with two query calls, the first one to get the author:

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

and the second one to find all the books of a given author:

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

you can get the same result of a common SQL Query that uses JOIN.

The N+1 problem could for example appear when we want to get 100 books, each with its author name:

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

In this case, we need to execute 1+100 queries, one to get the books list and 100 to dereference all the authors objects to get the author's name (this step is implicitly done on book.author.name statement).

One common technique to workaround this problem is by using get_value_for_datastore method that retrieves the referenced author's key of a given book without dereferencing it (ie, a datastore fetch):

author_key = Book.author.get_value_for_datastore(book)

There's a brilliant blog post on this topic that you might want to read.
This method, starting from the author_key list, prefetches the authors objects from datastore setting each one to the proper entity book.
Using this approach saves a lot of calls to datastore and practically * avoids the N+1 problem.

* theoretically, on a bookshelf with 100 books written by 100 different authors, we still have to call the datastore 100+1 times

Answering your question:

  • Google App Engine does not support eager fetching
  • There are techniques (not out of the box) that helps to avoid the dreaded N+1 problem
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜