当您需要查询多个实体(成千上万)时,强大的一致性



在每个注册管理员用户都有许多'商店'的应用程序中>'。拥有多个客户(在某些情况下为100个客户)每个客户都有一个帐户可以跟进他们的购买和过去订单。每个商店都为客户生成发票,客户支付发票。

Admin User -- > Shop 
Shop ---> clients
      |-> items Categories
      |-> items
      |-> invoices
      |-> payments received

管理员页面显示了一份报告,显示了一年内(从1月至12月)之内的发票。此页面是客户的要求。购买时,商店可以手动生成新的发票,并在付款时记录付款。注意:这一切都发生在实际商店,没有在线客户购买。

作为一家商店每月几乎没有发票(〜100秒),每月付款(〜100),每年很容易地向成千上万的实体显示在一页上显示。

要优化加载页面并生成销售年度报告(总销售,收入,付款等),我们认为我们以每年每个项目类别的方式构建数据也是一个实体。这意味着,每当该类别中的商品进行购买时,我们都需要将商品的购买价格添加到本月的 itemcategory

itemCategory 模型:

itemCategory(ndb.Model):
    shopID = ndb.KeyProperty()
    year = ndb.IntegerProperty()
    monthly_sales = ndb.FloatProperty(repeated=True) #12 months

这样,我们就可以通过仅阅读今年的这家商店的 itemcategory 的列表来加载整个销售表,而不是全年阅读所有个人购买。这将节省大量数据存储读取并减少页面加载时间,费用为额外的读取,sum&写入此摘要,例如实体。

Category      Jan   Feb   Mar ... Dec
--------------------------------------
Men's shoes   1000  1300  850 ... 1400
Kids shoes     600   850  650 ...  900

目前的挑战是,对于个人购买和ItemCategory实体而言,强大的一致性至关重要。因为如果商店试图以连续的短时间添加多次购买,那么最终的一致性ItemCategory可能尚未使用上次购买额来更新。导致错误的销售价值。如果个人购买需要在添加后立即进行编辑,那么对于没有其ID的实体的查询可能没有结果,也没有结果。因此,似乎祖先的查询至关重要,也许是商店作为父母的实体。但是,这将在稍后(至少直到数据存储迁移到Firestore)的所有这些实体(在这种情况下为数千个!)有一个单亲父母!

发票也是如此,生成新的发票意味着知道最新的发票号码,以便它们始终是顺序没有差距。最终一致性的查询发票可能会导致重复的发票号码。

此时构建数据的最佳方法是什么?不幸的是,该项目已经存在了几年,并开始使用Google数据存储而不是Cloud SQL(这似乎更适合这种项目)。希望所有这些问题在迁移到Firestore之后都消失了

考虑导出数据,然后将其导入数据存储模式项目中的云爆炸。最终不再有一体问题。

有某些方法可以实现强大的一致性。

  1. 使用key查询。每当您尝试通过其密钥读取对象时,它是strongly consistent
  2. 另一种方法是使用NDB异步操作。请参阅相关文档此处。
  3. 一种真正幼稚的方法是提供一个可以帮助您的延迟,但应以使对象更新的方式提供延迟。
  4. 最终的方法可能是将数据导出到云燃烧中。在那里您可以始终达到强大的一致性。

希望这回答您的问题!

最新更新