【发布时间】:2019-08-03 14:06:23
【问题描述】:
在具有许多“商店”的应用程序中,每个注册管理员用户都有一个“商店”实体,每个商店销售的商品属于某个“类别”。拥有多个客户(在某些情况下为 100 个),每个客户都有一个帐户来跟进他们的购买和过去的订单。每个商店都为其客户生成发票,客户支付发票。
Admin User -- > Shop
Shop ---> clients
|-> items Categories
|-> items
|-> invoices
|-> payments received
管理页面显示了一份报告,其中显示了一年内(从 1 月到 12 月)的发票此页面是客户要求的。商店能够在购买时手动生成新发票,并在付款时记录付款。注意:这一切都发生在实体店,没有在线客户购买。
由于一家商店每月生成的发票很少(约 100 份),每月生成多笔付款(约 100 份),因此每年很容易将这一点显示在数千个实体上以显示在一个页面上。
为了优化页面加载和生成销售年度报告(总销售额、收入、付款等),我们认为我们应该以一种每年的每个项目类别 em> 也是一个实体。这意味着每当购买此类别中的某件商品时,我们需要将该商品的购买价格添加到本月该年的itemCategory。
itemCategory 型号:
itemCategory(ndb.Model):
shopID = ndb.KeyProperty()
year = ndb.IntegerProperty()
monthly_sales = ndb.FloatProperty(repeated=True) #12 months
这样,我们可以通过仅读取该商店今年的 itemCategory 列表来加载整个销售表,而不是读取全年的所有个人购买。这将节省大量数据存储读取并减少页面加载时间,但代价是额外读取、汇总和写入此摘要(如实体)。
Category Jan Feb Mar ... Dec
--------------------------------------
Men's shoes 1000 1300 850 ... 1400
Kids shoes 600 850 650 ... 900
此时的挑战是,对于个人购买和 itemCategory 实体而言,强一致性非常重要。因为如果商店尝试以连续的短时间方式添加多个购买,最终一致性 itemCategory 可能尚未更新为最后的购买金额。导致错误的销售价值。如果需要在添加后立即对其进行编辑,则对于个人购买也是如此,对没有 ID 的实体的查询可能没有结果。所以看起来祖先查询在这里是必不可少的,也许商店是父实体。然而,这将导致稍后(至少在将 Datastore 迁移到 Firestore 之前)所有这些实体(在本例中为数千个!)只有一个父级的争用问题!
发票也是如此,生成新发票意味着知道最新的发票编号,以便它们始终按顺序排列,没有间隙。查询最终一致的发票可能会导致发票号码重复。
此时构建数据以实现强一致性的最佳方式是什么?不幸的是,该项目已经存在了几年,并且开始使用 Google Datastore 而不是 Cloud SQL(这似乎更适合此类项目)。希望在迁移到 Firestore 后,所有这些问题都会消失,所有读取都具有强一致性
【问题讨论】:
标签: python-2.7 google-cloud-datastore datastore