我想在我的应用中记录用户活动,以便向用户展示,也可以用于管理目的。我的客户是公司,所以我可以在三个级别上展示活动:
要进行日志记录,我会创建一个模型来存储日志条目。我看到了一些这样做的方法。
首先,我可以将每个记录的活动存储在自己的实体中,然后根据需要进行查询:
class Activity(ndb.Model):
activity = ndb.StringProperty()
user_id = ndb.StringProperty()
company_id = ndb.StringProperty()
其次,我可以将用户的所有活动存储在一个实体中:
class UserActivity(ndb.Model):
activity = ndb.StringProperty(repeated=True) # Note this is now a list
company_id = ndb.StringProperty()
第三,我可以将公司的所有活动存储在一个实体中:
class CompanyActivity(ndb.Model):
activity = ndb.StringProperty(repeated=True) # Would store user_id here somehow
这三个选项的功能/性能权衡是什么?我知道如果频繁出现交易,第二和第三选项存在潜在的争用问题,但是为了讨论,我们假设这不是问题。
对于第二个和第三个选项,减少数据存储区实体的总数是否有任何显着优势(因为它们将合并为更少的实体)?或者我应该选择第一个选项?
答案 0 :(得分:3)
使用重复属性的唯一好处是,您可以避免最终的一致性问题:每当您阅读UserActivity
或CompanyActivity
实体时,您都会知道自己获得了所有活动的完整列表。使用第一种方法时,您必须进行查询以获取此类列表,并且列表可能会错过最近的活动,因为相应的查询索引可能尚未更新以反映它们。
但是,除了您提到的潜在争用问题之外,重复属性方法还有另一个缺点:随着越来越多的活动被添加到列表中,这些实体的大小将逐渐增加,这意味着成:
get()
/ put()
次,因此整体应用性能逐渐恶化特别是第3种方法还需要一种不那么简单的方法来获取每用户活动报告。
我坚持第一种方法,它是最灵活和可扩展的方法,缺点很小:
Activity
实体中的用户/公司ID属性加上较大的索引,因为实体数量较多)是恕我直言,值得(存储便宜)。答案 1 :(得分:0)
我还建议第一种方法,但使用KeyProperty
:
class Activity(ndb.Model):
activity = ndb.StringProperty()
user_id = ndb.KeyProperty(kind='User')
company_id = ndb.KeyProperty(kind='Company')
代码从一开始就会更加清晰,您可以随时进行微调。
对于其他人来说,Dan已经非常清楚地涵盖了最重要的一点。