GAE数据存储多对多关系查询

时间:2013-08-07 19:37:05

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

故事:

假设您正在创建一个网站,人们可以根据自己喜欢的电影互相搜索。因此,您有UserMovie作为主要的两个实体。在关联UsersMovies以捕捉喜爱电影的概念时,几乎没有选择。

首先:在Movie

上创建User键列表

模型可能看起来像这样

class User(ndb.Model):
    username = ndb.StringProperty()
    userid = ndb.IntegerProperty()
    email = ndb.StringProperty()
    favorite_movies = ndb.KeyProperty(kind=Movie, repeated=True)

class Movie(ndb.Model):
    title = ndb.StringProperty()
    description = ndb.TextProperty()

第二:为关系创建一个单独的实体

模型可能如下所示

class User(ndb.Model):
    username = ndb.StringProperty()
    userid = ndb.IntegerProperty()
    email = ndb.StringProperty()

class Movie(ndb.Model):
    title = ndb.StringProperty()
    description = ndb.TextProperty()

class FavoriteMovie(ndb.Model):
    user = ndb.KeyProperty(kind=User)
    movie = ndb.KeyProperty(kind=Movie)
    rating = ndb.IntegerProperty()

采用第二种方法的好处之一是我们可以添加关于关系的其他信息,例如用户给他/她最喜欢的电影的评级。考虑第二种方法的另一个原因是双方是否有很多关系。在这个例子中,用户有很多喜欢的电影,很多用户都喜欢这部电影。

现在说我们不知道人们会不会有很多喜欢的电影,或者电影是否会被很多人所青睐,我们希望能够灵活变通,以便我们不需要匆忙改变设计。此外,您可能希望让用户在某个时刻评价他们喜欢的电影,并再次希望在那里有一些灵活性。但是,我们知道的一件事是,如果这个网站变大,效率就是王道,最终如果灵活性意味着效率降低,我们宁可不要失去效率。第二种方法引起关注,因为文档警告我们需要额外调用数据库来遍历关系。

所以要知道效率是否会成为一个问题,我们需要查看我们需要运行的查询类型,在我们的例子中,最常执行的查询将是“给我所有拥有Forest Gump的用户”作为最喜欢的电影“或”给我所有拥有Forest Gump和Cast Away作为最喜欢的电影的用户“。我们还需要知道我们需要什么数据。我们很可能不需要整个用户回来查询这些查询,而只需要一个名称和一张照片来构建我们在UI上的用户列表。鉴于此,我们可以对我们的数据进行非规范化处理,并将用户的姓名和照片网址放在关系上。执行此操作将允许我们避免对数据库进行后续调用以获取该数据,如果该人实际上选择用户查看他/她的配置文件,那么我们可以调用数据库。

问题:

这些是关于类似于上述问题的想法。正如你可能会说我倾向于使用第二种方法来模拟我的多对多关系。然而,我有一个主要问题。在我给出的第二个查询示例中,我要求Forest Gump AND Cast Away的用户为收藏夹。我不知道如何通过第二种方法有效地完成这项工作,用户能够提出这类问题至关重要。此外,对于使用Forest Gump OR Cast Away作为收藏的用户有什么影响。这些担忧是否足以使用第一种方法,还是有一种更好的方法,我在这里没有考虑过?

我很欣赏有关这个主题的任何想法。

谢谢, 汤姆

0 个答案:

没有答案