Google app engine 如何布局GAE数据存储 介绍
我是GAE的新手,写了一个小应用程序,不幸的是,虽然数据存储中没有太多数据,但它每天的读取速度非常快,达到了数据存储的配额限制。Google app engine 如何布局GAE数据存储 介绍,google-app-engine,google-cloud-datastore,Google App Engine,Google Cloud Datastore,我是GAE的新手,写了一个小应用程序,不幸的是,虽然数据存储中没有太多数据,但它每天的读取速度非常快,达到了数据存储的配额限制。 这个问题应该是关于布局和索引的可能使用(目前我不知道如何使用它们) 应用程序应该做什么 应用程序应该记录纸牌游戏的分数(对于那些感兴趣的人来说^^)。一场比赛由几轮组成,当一队得分达到1000分时结束 应用程序应显示已玩游戏的统计信息 应用程序的第一个布局 我的第一种布局方法是使用以下实体: class Player(db.Model): Name = d
这个问题应该是关于布局和索引的可能使用(目前我不知道如何使用它们) 应用程序应该做什么
- 应用程序应该记录纸牌游戏的分数(对于那些感兴趣的人来说^^)。一场比赛由几轮组成,当一队得分达到1000分时结束
- 应用程序应显示已玩游戏的统计信息
class Player(db.Model):
Name = db.StringProperty(required = True)
class Game(db.Model):
Players = db.ListProperty(db.Key)
Start = db.DateTimeProperty(auto_now_add = True, required = True)
End = db.DateTimeProperty()
class Round(db.Model):
Game = db.Reference(Game, required = True)
RoundNumber = db.IntegerProperty(required = True)
PointsTeamA = db.IntegerProperty(required = True)
PointsTeamB = db.IntegerProperty(required = True)
FinishedFirst = db.ReferenceProperty(Player, required = True)
TichuCalls = db.ListProperty(db.Key)
正如您在上面看到的,这些实体是规范化的(至少我希望是这样)。然而,使用这种方法,简单的计算如下
- 哪位选手赢得的比赛最多
#Untested snippet just to get an idea of what I am doing here
Wins = dict.fromkeys(Player.all().fetch(None), 0)
for r in Round.all():
wins[r.FinishedFirst] += 1
还有其他统计数据,比如
- 哪位选手最常先完成
- 哪位选手获胜率最高
- 等等
这导致了我的第二种方法: 应用程序的第二个布局 现在,每一场
游戏
都会存储一个不再是db.Model的回合列表
。这大大减少了数据集的读取量
问题
BlobProperty
存储非db.Model类型的对象有意义吗?)
简短回答-习惯于不“规范化”数据。这就是NoSQL DBS的优点。我会在玩家模型中添加一个列表属性或一组整数属性(无论哪个对你的应用程序更有意义),跟踪他们的游戏结束。像这样:
class Player(db.Model):
Name = db.StringProperty(required = True)
FinishedFirst = db.IntegerProperty(default=0)
FinishedSecond = db.IntegerProperty(default=0)
...
或
关键是,这两种方法都将帮助您避免查询/使用更多资源,然后以编程方式尝试计算用户在第一次中完成了多少次
当您拥有知道将要大量使用的数据时,请考虑在主模型中存储冗余属性,这样就可以随时使用,而无需重新查询
另外,看看NDB API
您可以利用JsonProperty进行游戏回合
归根结底,规范化是老式的RDB东西 考虑在免费获得memcaching时使用ndb.models(保存数据存储读取/写入)使用ndb属性,您可以得到一个重复的属性/结构,它可能会取代整个循环属性。有没有一种好方法可以确保数据存储中的冗余信息同步且不相互冲突?这是存储冗余信息的一个缺点-写入次数过多,这肯定会减少阅读量。第一道防线是确保您知道存储相同数据的所有位置,例如名称,并且每次更新名称时,确保以编程方式更新每个相对实体。第二道防线是创建经常运行的cron作业,自动比较数据,如果数据与某个基本实体不同步,则更新它。你不应该依赖这个。它表示数据不同步的时间段。
class Player(db.Model):
Name = db.StringProperty(required = True)
FinishedFirst = db.IntegerProperty(default=0)
FinishedSecond = db.IntegerProperty(default=0)
...
class Player(db.Model):
Name = db.StringProperty(required = True)
Finishes = db.ListProperty() # A list of 1s, 2s, 3s, etc... for each finish