【问题标题】:How to properly save data in GAE datastore?如何在 GAE 数据存储中正确保存数据?
【发布时间】:2012-02-25 09:33:57
【问题描述】:

我需要保留如下数据:

field1value=SomeStringValue
field1score=10
field2value=SomeOtherValue
field2score=20
...
fieldNvalue=SomeNValue
fieldNscore=N

即我有 N 个字段,每个字段都有自己的名称、存储在那里的值和分数。如何在 GAE 数据存储中正确存储此类数据?数据应该可以通过字段名称轻松访问。我还需要计算最终分数 (field1score + field1score + ... + fieldNscore)。

N 在 100 左右,数据库中的记录总数会很大。

更新。我使用了以下方法,但看起来它不是最好的:

class User(db.Model):
    field_names = db.StringListProperty()
    field_values = db.StringListProperty()
    field_scores = db.ListProperty(int)
    score_value = db.IntegerProperty()

def fields_add(user_key_name, field_name, field_value, field_score):
    user = User.get(user_key_name)
    if user:
        field_names = user.field_names
        field_values = user.field_values
        field_scores = user.field_scores
        if field_name in user.field_names:
            field_index = user.field_names.index(field_name)
            field_values[field_index] = field_value
            field_scores[field_index] = field_score
        else:
            field_names.append(field_name)
            field_values.append(field_value)
            field_scores.append(field_score)
        user.field_names = field_names
        user.field_values = field_values 
        user.field_scores = field_scores
        # TODO: update user.score_value
        user.put()

【问题讨论】:

    标签: google-app-engine google-cloud-datastore


    【解决方案1】:

    这取决于您的访问模式。了解更多细节和要求可以得到更好的答案。

    如果您将有超过 5000 个条目无法分开,则应使用如下所示的简单结构。要获得分数的总和,您可以查询所有并将它们添加到内存中。如果您有大量的分数,您可以使用MapReduce 按需查找总和,或使用shard counter 保持运行总和。

    class Score(db.Model):
      value = db.StringProperty()
      score = db.IntegerProperty()
    

    如果您的条目不超过 5000 个,您可以使用ListProperty。这将导致数据存储区的读取和写入次数大大减少,因为只有一个查询可以返回所有结果,然后您可以在内存中求和。如果您有一些第三条数据(如下面的玩家字段),您可以使用它来保证您的条目少于 5000,这可能是一个不错的解决方案。

    class Score(db.Model):
      player = db.StringProperty()
      values = db.StringListProperty()
      scores = db.ListProperty(int)
    

    【讨论】:

    • 数据存储中的记录总数将超过 5000。但字段数(以上N)将在 100 左右。
    【解决方案2】:

    可能取决于您的访问模式是什么样的,以及 N 的最大值是多少。

    最简单的方法是维护两个ListProperties:

    from google.appengine.ext import db
    
    class MyClass(db.Model):
      valueList = db.StringListProperty()
      scoreList = db.ListProperty(int)
    

    【讨论】:

    • 谢谢,乌鸦。字段名称是什么?我应该有第三个列表吗?
    • @LA_ 如果您的字段名称列表是静态的,您可能希望维护名称索引查找,甚至不将它们存储在 User 类中。只需将每个人初始化为具有良好默认值(零?)的相同大小的数组。但是,如果您想根据特定的命名分数进行任何查询,您可能需要考虑明确列出每个字段,而不是将值/分数存储在列表中。我很确定这可以动态完成 - 无需输入 200 个属性(如果字段列表不是静态的,也许 Expando 模型是合适的)。
    猜你喜欢
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多