如何在AppEngine数据存储区中映射两个巨大集合之间的关系

时间:2012-03-06 17:43:29

标签: google-app-engine google-cloud-datastore

我有一个可能有数百万条或更多条目的MOdelA和ModelB,它在数据存储区中可能不会超过300000个条目。

我将为ModelA创建大多数新条目(每秒约1 - 100)ModelA的每个实体都属于ModelB描述的类别之一

我需要能够查询属于其中一个ModelB实体的所有ModelA实体(按创建时间排序)。

我的问题是我不确定如何映射关系。我不能使用父母,因为在路上会有ModelA可能属于的MOdelC。

任何想法都想在AppEngine中映射它?

在常规SQL数据库中,我将创建一个数据透视表,将ModelA映射到ModelB,然后创建另一个数据透视表映射ModelA到ModelC。然后我可以查询数据透视表,例如给我所有属于模型B的模型ID。

非常感谢您的任何建议!

更新:

我认为解释我的问题的最佳方式将是我正在尝试做的一个例子。

假设我有消息和城市实体。每条消息都由用户发布有关城市的信息(这些是我的ModelA和ModelB)。现在,用户可以根据自己的喜好添加任意数量的城市。

我必须以用户只看到他们在收藏夹中拥有的城市的消息(按日期排序)的方式设计数据模型。所以Sean Fujiwara在下面提出的例子是行不通的。

我必须查询这样的内容:

db.GqlQuery("SELECT * FROM Message WHERE city IN (1, 2, 3, 4, ....)

这无法扩展,因为用户可能会将很多城市添加到收藏夹中。因为在AppEngine文档中他们说:

  

包含not-equal或IN运算符的单个查询限制为不超过30个子查询。

并且每个IN查询为IN(...)

中的每个条件生成多个==查询

感谢您的任何建议!

3 个答案:

答案 0 :(得分:1)

您正在考虑关系数据库架构。 Google Datastore是一个基于地图的数据库,因此您希望对表进行反规范化。这几乎意味着您的架构将由您的应用程序代码而不是数据库或模型声明强制执行。

这篇文章解释得很好: http://highscalability.com/how-i-learned-stop-worrying-and-love-using-lot-disk-space-scale

答案 1 :(得分:0)

听起来你想做的事情非常简单:

class ModelA(db.Model):
    b = IntegerProperty()
    creation_time = DateTimeProperty(auto_add_now = True)

class ModelB(db.Model):
    category_name = StringProperty()

b_id = 5

query = db.Query(ModelA)
query.filter('b =', b_id)
query.order('creation_time')
rows = query.fetch(100)

答案 2 :(得分:0)

听起来你想要一种无主的双向关系。一种方法是在每一侧创建一个键列表。如果你使用的是像JPA这样的东西,基本上你在用户和城市之间就有了一个ManyToMany关系。用户和消息之间的OneToMany关系。和城市和消息之间的OneToMany关系。

因此,要获取消息,您基本上会查询加入您用户的消息列表。然后,您可以通过从用户返回您最喜爱的城市列表,将城市从您最喜欢的城市中的邮件中拉出来。

Datanucleus现在也提供无关的关系。

http://datanucleus.blogspot.com/