【问题标题】:Creating your own activity logging in GAE/P在 GAE/P 中创建自己的活动记录
【发布时间】:2018-03-29 12:24:05
【问题描述】:

我想在我的应用中记录用户活动,以便向用户展示和管理。我的客户是公司,因此我可能会在三个级别上展示活动:

  1. 单个用户的活动
  2. 公司所有用户的活动
  3. 所有活动

要进行日志记录,我将创建一个模型来存储日志条目。我看到了几种方法。

首先,我可以将每个记录的活动存储在其自己的实体中,然后根据需要进行查询:

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

这三个选项的功能/性能权衡是什么?我知道如果有频繁的看跌交易,第二个和第三个选项可能存在争用问题,但为了讨论,我们假设这不是一个问题。

对于第二个和第三个选项,减少数据存储实体的总数(因为它们将被合并到更少的实体中)是否有任何显着优势?还是我应该选择第一个选项?

【问题讨论】:

    标签: python google-app-engine


    【解决方案1】:

    使用重复属性的唯一好处是您可以避免最终的一致性问题:每当您读取UserActivityCompanyActivity 实体时,您就会知道您获得了完整 所有活动的列表。使用第一种方法时,您必须进行查询以获取此类列表,并且该列表可能会错过最近的活动,因为相应的查询索引可能尚未更新以反映它们。

    但是,除了您提到的潜在争用问题之外,重复属性方法还有一个缺点需要考虑:随着越来越多的活动被添加到列表中,这些实体的大小将逐渐增加,这意味着进入:

    • 越来越慢get()/put() 倍,因此整体应用性能逐渐下降
    • 存在达到最大数据存储实体大小(~ 1MB,请参阅Limits)的风险,这需要额外的逻辑来将列表拆分到多个实体中

    特别是第 3 种方法还需要一种不那么简单的方法来获取每个用户的活动报告。

    我会坚持第一种方法,它是最灵活和可扩展的方法,缺点很小:

    • 最终的一致性问题是恕我直言,而不是阻碍(并且可能有减少其影响的方法)
    • 额外的存储空间(用于存储在每个 Activity 实体中的用户/公司 ID 属性以及由于更多实体而导致的更大索引)非常值得恕我直言(存储很便宜)。

    【讨论】:

    • 谢谢,这一切都说得通,并确认了我的倾向,即使实体大小不是问题(我将修剪日志)并且最终一致性不是问题(不要'不需要最新的更新)。
    【解决方案2】:

    我也建议第一种方法,但使用KeyProperty

    class Activity(ndb.Model):
        activity = ndb.StringProperty()
        user_id = ndb.KeyProperty(kind='User')
        company_id = ndb.KeyProperty(kind='Company')
    

    代码从一开始就会更简洁,以后您可以随时进行微调。

    对于其余部分,Dan 已经很好地涵盖了最重要的点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-17
      • 1970-01-01
      相关资源
      最近更新 更多