【问题标题】:Fetching by key vs fetching by filter in Google App Engine在 Google App Engine 中按键获取与过滤器获取
【发布时间】:2012-04-27 04:50:51
【问题描述】:

我希望尽可能高效并妥善计划。由于在使用 Google App Engine 时读取和写入成本很重要,因此我希望确保将这些成本降至最低。我不理解数据存储中的“关键”概念。我想知道的是,考虑到我知道它是什么,通过键来获取实体是否比通过某种过滤器获取更有效?

假设我有一个名为 User 的模型,并且一个用户有一个 commentId 数组(列表)。现在我想得到这个用户的所有 cmets。我有两个选择:

  1. 用户的commentId 数组是一个键数组,其中每个键都是一个Comment 实体的键。因为我有所有的钥匙,所以我可以通过他们的钥匙来获取所有的 cmets。

  2. 用户的commentId 数组是我自定义的标识符,在这种情况下,假设它们是自动递增的常规整数,并且数据存储中的每个评论都有一个唯一的commentIntegerId。所以现在如果我想获取所有的 cmets,我会根据我的 ids 数组中的 ID 的所有 cmets 进行过滤获取。

哪种实现会更有效,为什么?

【问题讨论】:

  • 您是否考虑过第三种选择:用户键是该用户评论键的父级(祖先)?
  • 你能详细说明一下吗..
  • 意思是,不用在你的用户模型上使用属性列表,你只需使用数据存储结构:评论键有一个父级,一个用户键。因此,稍后,当您想要获取用户制作的所有 cmets 时,您可以执行例如Comment.query(ancestor=user_key)(在 Python、NDB 中)或 ds.prepare(new Query("Comment", userKey))(Java)。换句话说,您不会为了保存评论键列表而保留任何其他实体属性。
  • 我明白了..so 获取所有具有共同祖先(作为某个用户)的 cmets 比获取具有过滤器 ownerId=5 的所有 cmets 更快?
  • 是的,我相信是的。不过,这一切都取决于围绕您的特定问题的数据。您还应该考虑实现以后维护代码的成本。这总是一个权衡。我强烈推荐的工具之一是 Appstats - 它会告诉您在 HTTP 请求/响应期间您正在制作多少个 RPC 以及您正在消耗多少 CPU(假设您在该请求期间进行查询)。

标签: database google-app-engine


【解决方案1】:
  1. 按键获取是从数据存储中获取实体的最快方式,因为它是最直接的操作,不需要通过索引查找。
  2. 每次创建条目时(除非您指定 key_name),应用引擎都会生成一个唯一的(每个父实体)数字 id,您应该将其用作 cmets 的 id。

【讨论】:

  • 您能详细说明第 1 点吗?为什么它是最快的方式?
  • @mohabitar:一个务实的答案会指向你the app engine system status,单个数据存储获取(按键获取)大约需要 30 毫秒,而单个查询需要大约 90 毫秒。
  • @IbrahimArief 顺便说一句,HR 数据存储获取时间 adv 大约是 30 毫秒,而(旧的和“坏”的)MS 数据存储大约是 15 毫秒。
【解决方案2】:

您应该根据使用模式设计一个 NoSql 数据库(= GAE 数据存储):

如果您需要一次获取所有用户的 cmets,并且从不需要基于某些条件(例如查询它们)获取其中一个或一些,那么就速度而言,最有效的方式成本是将所有 cmets 序列化为实体内的二进制 blob(或将其保存到 Blobstore)。

但我想情况并非如此,因为 cmets 通常与用户和帖子相关联,对吧?在这种情况下,上述建议将不可行。

回答你的标题问题:get by key 总是比query by a property 更快,因为查询首先通过索引来满足属性条件,它在哪里获取 key,然后它执行 get用这把钥匙。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 2015-11-06
    • 1970-01-01
    • 2011-02-02
    • 2011-08-08
    • 2011-05-12
    • 1970-01-01
    相关资源
    最近更新 更多