试图摆脱关系思维的好工作。摆脱行/表思维是件好事。
至少在编程方面,更接近的近似值是将实体视为远程存储的数据结构或类实例。这些实体具有属性。与实体分开的是索引,它本质上存储与某些属性标准匹配的实体列表。
当您编写实体时,数据存储会更新内存/存储中的该实例,然后更新所有索引。
当您进行查询时,您实际上是遍历其中一个索引列表。
这应该为您提供一个考虑数据存储的基本框架。
当您为数据存储进行设计时,您通常必须针对成本进行设计,在较小程度上还需要考虑性能。在写入方面,您希望最小化索引的数量。在读取方面,您希望最大限度地减少正在读取的实体数量,因此为红色、蓝色、绿色设置单独实体的想法可能不是一个好主意,如果您经常需要回读数字,则读取成本会增加三倍红色/蓝色/绿色汽车。可能有一些非常模糊的角落案例,这是有道理的。
您的设计考虑通常应遵循以下原则:
- 我需要做哪些类型的查询?
- 我如何构建我的数据以使这些查询易于执行(因为 GAE 查询功能有限)?如果我以某种方式复制数据,查询会更容易吗?我是否能够自己维护这些复制的数据?
- 如何在更新实体时尽量减少需要更新的索引数量?
- 是否存在我必须具有完全一致性并因此需要调整结构以便进行一致查询的特殊情况?
- 有没有我需要注意的写入性能案例。
在不确切知道您将要进行哪种查询的情况下,这个答案可能不正确,但它应该说明您可能想如何思考这个问题。
我假设你有一个人们注册他们的汽车的应用程序,并且你有一些仪表板可以轮询数据存储并显示每种颜色的汽车数量,具有颜色的 Car 类的传统机制,计数属性仍然有意义,因为它最大限度地减少了索引属性的数量,从而降低了您的写入成本。
这是一个有点奇怪的例子,因为我不知道您是否只想拥有一个跟踪您的计数的实体(在这种情况下,您甚至不需要进行查询,您只需获取该计数),或者如果您有许多可以获取和汇总的计数实体。
如果用户更新修改了相同的实体,您可能会遇到性能问题,您应该阅读以下内容:https ://developers.google.com/appengine/articles/sharding_counters