2009-10-12 29 views
1

我看過從谷歌的I/2009 O此視頻:http://www.youtube.com/watch?v=AgaL6NGpkB8其中佈雷特顯示微博的例子。他介紹了兩種數據存儲模式:

第一一個:
class Message(db.Model):
    sender = db.StringProperty()
    body = db.TextProperty()
    receivers = db.StringListProperty()

之一:
class Message(db.Model):
    author = db.StringProperty()
    message = db.TextProperty()

class MessageIndex(db.Model)
    receivers = db.StringListProperty()

他說,在第一個例子中數據存儲都有我們每次查詢信息的時間序列化/反序列化接收機性能由接收者,而在第二個例子中沒有。我不明白爲什麼數據存儲在這個例子中表現不同,在這兩種情況下,接收者只是StringListProperty。你能解釋一下嗎?GAE數據存儲列表屬性系列化

回答

2

在他的談話,他假定當您查詢,您要檢索的消息的內容 - 「發件人」和「體」。在App Engine中,實體是作爲一個整體反序列化的 - 您不能只加載某些字段 - 因此,當您在第一個示例中執行查詢時,它必須加載整個接收者列表。

在第二個例子,可以做在一個MessageIndex僅鑰查詢,然後取和加載相應的消息的實體。因爲您從不將任何MessageIndex屬性加載到內存中,所以不需要反序列化與它們關聯的大型且昂貴的listproperty。

+0

我的理解它了,但還是謝謝你:)。你是絕對正確的。 – giolekva 2009-10-29 18:57:00

0

請注意,有一個新功能,投影查詢,這可以讓你得到你的實體的局部視圖,但僅限於索引屬性。

https://developers.google.com/appengine/docs/python/datastore/projectionqueries

它的內部工作原理,是你的實體鍵和索引都存儲在不同的表。如果你得到整個實體,你必須在主實體表中進行查找,這是很昂貴的,因爲它必須對整個事物進行反序列化(並且對該表中的任何其他進程都進行了反序列化)。

投影查詢就像是一個關鍵的查詢,但不是你的實體按鍵,它使用一組索引值的一個關鍵(因爲這是如何的索引表的內部操作)。如果你想要一個數據的子集並且可以證明支付是爲了索引它(或者它已經被編入索引),那麼投影查詢將會很快並且便宜。它只在索引表中查找,不需要觸及實體或關鍵字表。

+0

PS - 列表屬性非常昂貴,因爲它會在列表中的索引表PER項中創建一個條目。這樣你可以運行一個==查詢並返回任何匹配項。這是您想要避免的de/serialization的昂貴部分。這不僅僅是實體de /序列化變得昂貴;它是使用列表屬性更新值的寫入量(如果不小心手動聲明索引,則兩個列表屬性將呈指數形式)。 – Ajax 2013-01-04 13:38:30