I\'d like to log user activity in my app for presentation to users and also for administrative purposes. My customers are companies so there are three levels at which I may
I would also suggest the first approach but with KeyProperty
:
class Activity(ndb.Model):
activity = ndb.StringProperty()
user_id = ndb.KeyProperty(kind='User')
company_id = ndb.KeyProperty(kind='Company')
Code would be much cleaner from the start and you can always fine-tune later.
For the rest Dan has covered most important points really well.
The only advantage of using the repeated property would be that you'd avoid the eventual consistency problem: whenever you read a UserActivity
or CompanyActivity
entity you'll know that you get the complete list of all activities. When using the 1st approach you'd have to make a query to obtain such list and the list may miss very recent activities as the respective query index may not have yet been updated to reflect them.
But, in addition to the potential contention problem you mentioned, there is another disadvantage to consider for the repeated property approach: the size of these entities will gradually be increasing as more and more activities are being added to the list, which translates into:
get()
/put()
times, so gradually deteriorating overall app performanceThe 3rd approach in particular will also require a less trivial method of obtaining per-user activity reports.
I'd stick with the 1st approach, it's the most flexible and scalable approach and the disadvantages are minor:
Activity
entity plus larger indexes due to the higher number of entities) is IMHO well worthy (storage is cheap).