考慮一個允許用戶評論歌曲的GAE(python)應用程序。預期用戶數量爲1,000,000+。預計的歌曲數量是5000。如何計算Google App Engine中多對多關係的雙方
應用程序必須能夠:
- 給歌曲的用戶已經對
- 評論數給誰有一首歌
計數器管理必須評論的用戶數是事務性的,以便它們始終反映基礎數據。
看起來,GAE應用程序必須始終保持這些計數類型的計數,因爲在請求時查詢它們將是低效的。
我的數據模型
class Song(BaseModel):
name = db.StringProperty()
# Number of users commenting on the song
user_count = db.IntegerProperty('user count', default=0, required=True)
date_added = db.DateTimeProperty('date added', False, True)
date_updated = db.DateTimeProperty('date updated', True, False)
class User(BaseModel):
email = db.StringProperty()
# Number of songs commented on by the user
song_count = db.IntegerProperty('song count', default=0, required=True)
date_added = db.DateTimeProperty('date added', False, True)
date_updated = db.DateTimeProperty('date updated', True, False)
class SongUser(BaseModel):
# Will be child of User
song = db.ReferenceProperty(Song, required=True, collection_name='songs')
comment = db.StringProperty('comment', required=True)
date_added = db.DateTimeProperty('date added', False, True)
date_updated = db.DateTimeProperty('date updated', True, False)
代碼
此處理用戶的歌曲算事務而不是歌曲的用戶數。
s = Song(name='Hey Jude')
s.put()
u = User(email='[email protected]')
u.put()
def add_mapping(song_key, song_comment, user_key):
u = User.get(user_key)
su = SongUser(parent=u, song=song_key, song_comment=song_comment, user=u);
u.song_count += 1
u.put()
su.put()
# Transactionally add mapping and increase user's song count
db.run_in_transaction(add_mapping, s.key(), 'Awesome', u.key())
# Increase song's user count (non-transactional)
s.user_count += 1
s.put()
的問題是:我怎樣才能事務管理兩個計數器?
基於我的理解,這將是不可能的,因爲用戶,歌曲和SongUser必須是相同的entity group的一部分。他們不能在一個實體組中,因爲那時我的所有數據都將在一個組中,並且不能由用戶分配。
您的解決方案可以減少爭用,但我真正想要做的是確保兩個計數器都匹配底層'SongUser'記錄。如果我使用'Song'實體的分片計數器,那麼當創建'SongUser'時仍然可以成功,並且增加歌曲的計數器失敗(反之亦然)。 – cope360 2010-02-11 15:09:59
已注意。我更新了我的答案以反映您的擔憂。 – 2010-02-11 15:55:43
我認爲最後一段中的解決方案可能是GAE限制中的最佳選擇。在那個解決方案中,我們翻轉了我第一個評論的例子。例如,現在可以更新/創建樂曲計數器和SongUser記錄,但用戶記錄更新失敗(反之亦然)。你是否同意不可能更新兩個計數器(分片還是不分片)? – cope360 2010-02-11 17:34:44