1

我正在建模数据,哪些 ID 应该是自动递增的。实际上,我已经制作了工作模型,但需要数据存储大师的一些建议。

有我的 ID 生成代码:

class AutoIncrementModel(ndb.Model):
  entity_id = ndb.IntegerProperty('eID')
  def _pre_put_hook(self):
    if self.key and self.key.id(): return
    latest = self.__class__.query().order(-self.__class__.entity_id).get()
    self.entity_id = latest and latest.entity_id + 1 or 1
    while self.__class__.get_by_id(self.entity_id): self.entity_id += 1
    self.key = ndb.Key(self.__class__.__name__, self.entity_id, parent=self.key and self.key.parent() or None)
    self.put()

此代码生成简单的 ID,但我不确定它是否足够好。

UPD此代码失败。可以使用相同的键写入多个实体,并且可以覆盖数据。

№1。它会导致数据丢失问题吗?“While 循环”可防止应用生成 ID。但我不确定数据是否有可能被覆盖。

2号。这样的交易可以让储蓄更好吗?

  def _pre_put_hook(self):
    def callback():
      while self.__class__.get_by_id(self.entity_id): self.entity_id += 1
      self.key = ndb.Key(self.__class__.__name__, self.entity_id, parent=self.key and self.key.parent() or None)
      self.put()
    if self.key and self.key.id(): return
    latest = self.__class__.query().order(-self.__class__.entity_id).get()
    self.entity_id = latest and latest.entity_id + 1 or 1
    ndb.transaction(callback, xg=True)

UPD:事务有助于避免数据丢失。这段代码似乎比第一个例子好得多。

3号。有没有办法从没有额外索引字段的实体组中获取最大 ID?

4

2 回答 2

3

基本上这是做不到的。您需要一个外部计数器“单例”,如果您每秒需要超过一次写入,则应该添加共享以提高性能。有关选项的讨论,请参阅如何在 Google AppEngine 上实现“自动增量” 。

于 2012-05-13T13:11:16.590 回答
0

按“self.class .entity_id ”字段排序没有意义,因为该字段是唯一标识符,从不具有增量值,也没有添加任何意义。

于 2017-06-19T18:57:31.393 回答