Database 谷歌应用引擎中的键抓取与过滤器抓取

Database 谷歌应用引擎中的键抓取与过滤器抓取,database,google-app-engine,Database,Google App Engine,我希望尽可能的高效,并且计划得当。由于在使用谷歌应用程序引擎时,读写成本非常重要,所以我想确保将这些成本降至最低。我不理解数据存储中的“关键”概念。我想知道的是,考虑到我知道实体是什么,通过它的键来获取实体会比通过某种过滤器获取更有效吗 假设我有一个名为User的模型,一个用户有一个commentId数组(列表)。现在我想得到所有用户的评论。我有两个选择: 用户的commentId数组是一个键数组,其中每个键都是注释实体的键。因为我有所有的键,所以我可以通过它们的键获取所有的注释 用户的comm

我希望尽可能的高效,并且计划得当。由于在使用谷歌应用程序引擎时,读写成本非常重要,所以我想确保将这些成本降至最低。我不理解数据存储中的“关键”概念。我想知道的是,考虑到我知道实体是什么,通过它的键来获取实体会比通过某种过滤器获取更有效吗

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

  • 用户的commentId数组是一个键数组,其中每个键都是注释实体的键。因为我有所有的键,所以我可以通过它们的键获取所有的注释

  • 用户的commentId数组是我定制的标识符,在本例中,让我们说它们是自动递增的正则整数,数据存储中的每个注释都有一个唯一的commentIntegerId。因此,现在如果我想获取所有注释,我会根据ID数组中ID为的所有注释进行过滤获取

  • 哪种实现更有效,为什么

  • 按键抓取是从数据存储中获取实体的最快方法,因为它是最直接的操作,不需要进行索引查找
  • 每次创建条目时(除非您指定了key_name),应用引擎将生成一个唯一的(每个父实体)数字id,您应该将其用作注释的id
  • 按键抓取是从数据存储中获取实体的最快方法,因为它是最直接的操作,不需要进行索引查找
  • 每次创建条目时(除非您指定了key_name),应用引擎将生成一个唯一的(每个父实体)数字id,您应该将其用作注释的id

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

    如果您需要一次获取所有用户的注释,并且永远不需要基于某些条件获取其中一条或多条注释(例如查询注释),那么从速度和成本方面来说,最有效的方法是将所有注释序列化为实体内的二进制blob(或将其保存到Blobstore)

    但我想情况并非如此,因为评论通常都与用户和帖子联系在一起,对吗?在这种情况下,上述建议将不可行


    回答标题问题:
    get
    by key总是比
    query
    by property快,因为query首先通过索引来满足属性条件,在这里它获取了键,然后用这个键执行
    get

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

    如果您需要一次获取所有用户的注释,并且永远不需要基于某些条件获取其中一条或多条注释(例如查询注释),那么从速度和成本方面来说,最有效的方法是将所有注释序列化为实体内的二进制blob(或将其保存到Blobstore)

    但我想情况并非如此,因为评论通常都与用户和帖子联系在一起,对吗?在这种情况下,上述建议将不可行


    回答您的标题问题:
    get
    by key总是比
    query
    by属性快,因为query首先通过索引来满足属性条件,在这里它获取了键,然后用这个键执行
    get

    您考虑过第三个选项吗:用户键是父(祖先)你能详细说明一下吗?意思是,你不用在你的用户模型上使用属性列表,你只需要使用数据存储结构:Comment key有一个父项,一个用户key。因此,稍后,当您想要获取用户的所有注释时,您可以执行例如
    Comment.query(祖先=用户密钥)
    (在Python中,NDB)或
    ds.prepare(新查询(“Comment”,userKey))
    (Java)。换句话说,您不需要保留任何额外的实体属性来保存注释键列表。我明白了。因此,使用一个共同祖先(作为某个用户)获取所有注释要比使用filter ownerId=5获取所有注释更快?是的,我相信是这样。不过,这完全取决于围绕您的特定问题的数据。您还应该考虑以后执行和维护代码会花费多少钱。这总是一种权衡。我强烈推荐的工具之一是Appstats,它会告诉您在HTTP请求/响应过程中(假设您在请求/响应过程中进行查询)正在生成多少RPC以及消耗多少CPU。您是否考虑过第三个选项:用户密钥是父级(祖先)你能详细说明一下吗?意思是,你不用在你的用户模型上使用属性列表,你只需要使用数据存储结构:Comment key有一个父项,一个用户key。因此,稍后,当您想要获取用户的所有注释时,您可以执行例如
    Comment.query(祖先=用户密钥)
    (在Python中,NDB)或
    ds.prepare(新查询(“Comment”,userKey))
    (Java)。换句话说,您不需要保留任何额外的实体属性来保存注释键列表。我明白了。因此,使用一个共同祖先(作为某个用户)获取所有注释要比使用filter ownerId=5获取所有注释更快?是的,我相信是这样。不过,这完全取决于围绕您的特定问题的数据。您还应该考虑以后执行和维护代码会花费多少钱。这总是一种权衡。我强烈推荐的工具之一是Appstats,它会告诉您在HTTP请求/响应过程中(假设您在请求/响应过程中进行查询)您正在制作多少个RPC以及消耗多少CPU。您是否有机会详细说明第1点?为什么这是最快的方法?@mohabitar:务实的回答会告诉你,一个数据存储获取(按键获取)需要约30毫秒,而一个查询需要约90毫秒。@IbrahimArief btw注意,HR数据存储需要时间