1

故事:

假设您正在创建一个网站,人们可以在该网站上根据他们最喜欢的电影相互搜索。所以你有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 的用户”电影”或“给我所有将《阿甘正传》和《放逐》作为最喜欢的电影的用户”。我们还需要知道何时需要什么数据。很可能我们不需要整个用户都回来进行这些查询,而只需要一个名字和一张照片就可以在 UI 上建立我们的用户列表。鉴于此,我们可以对我们的数据进行一些非规范化,并将用户名和照片 url 放在关系上。

问题:

这些是对与上述问题类似的问题的想法。正如您可能会说的那样,我倾向于使用第二种方法来模拟我的多对多关系。然而,我有一个主要的担忧。在我给出的第二个查询示例中,我询问了喜欢 Forest GumpCast Away 的用户。我不知道使用第二种方法如何有效地完成此操作,用户能够提出此类问题至关重要。此外,对于喜欢使用 Forest GumpCast Away 的用户会有什么影响。这些问题是否足以使用第一种方法,或者是否有更好的方法我在这里没有考虑过?

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

谢谢,汤姆

4

0 回答 0