2010-11-25 8 views
5

我有很多(如)帖子,標有一個或多個標籤。發佈可以被創建或刪除,並且用戶也可以對一個或多個標籤(與邏輯AND結合)進行搜索請求。即來到我的腦海 第一個想法是一個簡單的模型創建和刪除操作的Google App Engine上的高度可伸縮標籤(Python)

class Post(db.Model): 
    #blahblah 
    tags = db.StringListProperty() 

實現是顯而易見的。搜索更復雜。要搜索N個標籤,它將執行N個GQL查詢,例如「SELECT * FROM Post WHERE tags =:1」,並使用遊標合併結果,並且其性能非常糟糕。

二的想法是不同的實體

class Post(db.Model): 
    #blahblah 
    tags = db.ListProperty(db.Key) # For fast access 

class Tag(db.Model): 
    name = db.StringProperty(name="key") 
    posts = db.ListProperty(db.Key) # List of posts that marked with tag 

它通過密鑰(速度遠遠超過把它通過GQL),並在內存中合併的話,我覺得這個實現具有更好的性能需要的標籤從數據庫中分離標籤比第一個,但非常頻繁的可用標籤可以超過允許單個數據存儲對象的最大大小。另外還有一個問題:數據存儲只能修改一個單一的對象〜1 /秒,因此對於頻繁使用的標籤,我們也有一個修改延遲的瓶頸。

有什麼建議嗎?

回答

0

可能一個可能的解決方案是採取你的第二個例子,並修改它的方式,將允許更大的集合上有效的查詢。讓人想到的一種方式是將多個數據庫實體用於單個標籤,並將其分組,這樣您就很少需要獲得多個組。如果默認的排序順序(讓我們只將它稱爲唯一允許的)以後日期爲準,那麼按照該順序填充標籤組實體。

class Tag(db.Model): 
    name = db.StringProperty(name="key") 
    posts = db.ListProperty(db.Key) # List of posts that marked with tag 
    firstpost = db.DateTimeProperty() 

添加或移除標籤一組時,檢查,看看有多少帖子是該組中,如果添加會使帖子的帖子有不止,說100個職位,把它分解成兩個標記組。如果您要刪除帖子以便該帖子的帖子少於50個,請從上一個或下一個小組中竊取一些帖子。如果其中一個相鄰組還有50個帖子,則將它們合併在一起。按標籤列出帖子時(按日期順序排列),您只需獲得少數幾組。

這並不能真正解決高需求標籤問題。

考慮一下,插入可能會更好一些。獲取最新的標籤組條目,合併它們並放置一個新的標籤組。交易中的滯後可能實際上不是真正的問題。

+1

滯後可以通過實現日誌添加崗位來解決。當post被添加隊列時 - 它爲每個標記創建一個特殊對象,其中包含「Look!該帖子屬於該標記」的信息(並且還修改標記實體的Memcache副本),如果memcache副本已過期,則會創建日記應用程序收集所有日記條目並將其應用於數據存儲中的標記實體(並將其複製到memcache中)。 – 2010-11-25 20:23:08