如何在GAE数据存储中正确保存数据?

时间:2012-02-25 09:33:57

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

我需要保留以下数据:

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()

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

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

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

from google.appengine.ext import db

class MyClass(db.Model):
  valueList = db.StringListProperty()
  scoreList = db.ListProperty(int)