Рассмотрим приложение GAE (python), которое позволяет пользователям комментировать песни. Ожидаемое количество пользователей - 1000000+. Ожидаемое количество песен - 5000.
Приложение должно уметь:
- Укажите количество песен, которые прокомментировал пользователь.
- Укажите количество пользователей, которые прокомментировали песню.
Управление счетчиками должно быть транзакционным, чтобы они всегда отражали лежащие в основе данные.
Кажется, что приложения 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()
Возникает вопрос: как я могу управлять обоими счетчиками транзакциями?
Насколько я понимаю, это невозможно, поскольку User, Song и SongUser должны быть частью одного и того же группа объектов. Они не могут быть в одной группе сущностей, потому что тогда все мои данные будут в одной группе, и они не могут быть распределены пользователем.