Django:哪个数据库调用更快/更好?

时间:2022-05-22 12:52:12

I'm building an online internet game that people can log in to play. When people play a Game, they create a Result. In addition, they can Like Games and Results.

我正在建立一个人们可以登录玩的在线网络游戏。当人们玩游戏时,他们会创建一个结果。此外,他们可以喜欢游戏和结果。

My main question is, is there a significant difference in the way that I make calls to the database? There is a table for Games and there is a table for User Profiles. Would it make a difference if I save likes to a Game on the Game table, or if I save likes to a game_likes field on the User Profile table?

我的主要问题是,我调用数据库的方式有很大差异吗?有一个游戏桌,有一个用户配置文件表。如果我将喜欢保存到游戏桌上的游戏中,或者如果我将喜欢保存到用户配置文件表上的game_likes字段,它会有所不同吗?

For example, if my UserProfile looked like this:

例如,如果我的UserProfile看起来像这样:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='user_profile')
    games_liked = models.ManyToManyField(Game, related_name='games_liked')

and my Game model looked like this:

我的游戏模型看起来像这样:

class Game(models.Model):
    likes = models.ManyToManyField(User, related_name='likes')

Which would be better for making calls to the database? This:

哪个调用数据库更好?这个:

games_liked = Game.objects.filter(likes=request.user).order_by('-pubdate')

versus:

与:

games_liked = request.user.user_profile.games_liked.all()

I feel like the second example is better because it uses direct relations to pick the games instead of querying the entire Game index to figure out which games have been liked by the user, but a friend I was talking to said that Django and SQL index the databases so that it would be the same either way. Does it actually matter?

我觉得第二个例子更好,因为它使用直接关系来挑选游戏而不是查询整个游戏索引以找出用户喜欢哪些游戏,但我正在谈论的朋友说Django和SQL索引数据库,以便它们都是相同的。它真的重要吗?

Edit: My current site is saving to both a likes field on the Game and a game_likes field on the UserProfile, then counting the Game's likes field for likes and seeking the UserProfile game_likes field to see if the user has liked a game or not, but I don't know if it actually makes a difference or if duplicating the tables makes it not worth the difference in seek time.

编辑:我当前的网站正在保存游戏中的喜欢字段和UserProfile上的game_likes字段,然后计算喜欢的游戏喜欢字段并寻找UserProfile game_likes字段以查看用户是否喜欢游戏,但是我不知道它是否真的有所作为,或者重复表格是否值得寻找时间的差异。

1 个解决方案

#1


1  

request.user.user_profile makes an SQL query to get user profile, then user_profile.games_liked.all() makes second sql query to get liked games.

request.user.user_profile进行SQL查询以获取用户配置文件,然后user_profile.games_liked.all()进行第二次SQL查询以获得喜欢的游戏。

So, form this point of view Game.objects.filter(likes=request.user) is better.

因此,从这个观点来看,Game.objects.filter(likes = request.user)更好。

You can check what sql was executed, in shell, by looking into connection.queries variable (available only if setting DEBUG=True)

您可以通过查看connection.queries变量来查看shell中执行的sql(仅在设置DEBUG = True时可用)

from django.db import connection

user.user_profile.games_liked.all()
Game.objects.filter(likes=user)._as_sql(connection)

print(connection.queries)

Anyway, your example seems broken. ManyToMany field creates whole new table to store relationships. And you have linked games twice:

无论如何,你的例子似乎破了。 ManyToMany字段创建全新的表来存储关系。你有两次关联游戏:

  • UserProfile -> _m2m_table -> Games (by UserProfile.games_liked)
  • UserProfile - > _m2m_table - >游戏(通过UserProfile.games_liked)
  • User -> _m2m_table -> Games (by Games.likes)
  • 用户 - > _m2m_table - >游戏(由Games.likes提供)

You should remove one field.

你应该删除一个字段。

Django creates shortcuts to get access to relation from opposite side. That is what related_name stands for. So for your Game model, use have access to users by game.likes, and from user you have access to games by user.likes, b/c you have declared related_name='likes'

Django创建了快捷方式,以便从对方访问关系。这就是related_name所代表的含义。因此,对于您的游戏模型,使用可以通过game.likes访问用户,并且可以通过user.likes访问用户,b / c您已声明related_name ='likes'

#1


1  

request.user.user_profile makes an SQL query to get user profile, then user_profile.games_liked.all() makes second sql query to get liked games.

request.user.user_profile进行SQL查询以获取用户配置文件,然后user_profile.games_liked.all()进行第二次SQL查询以获得喜欢的游戏。

So, form this point of view Game.objects.filter(likes=request.user) is better.

因此,从这个观点来看,Game.objects.filter(likes = request.user)更好。

You can check what sql was executed, in shell, by looking into connection.queries variable (available only if setting DEBUG=True)

您可以通过查看connection.queries变量来查看shell中执行的sql(仅在设置DEBUG = True时可用)

from django.db import connection

user.user_profile.games_liked.all()
Game.objects.filter(likes=user)._as_sql(connection)

print(connection.queries)

Anyway, your example seems broken. ManyToMany field creates whole new table to store relationships. And you have linked games twice:

无论如何,你的例子似乎破了。 ManyToMany字段创建全新的表来存储关系。你有两次关联游戏:

  • UserProfile -> _m2m_table -> Games (by UserProfile.games_liked)
  • UserProfile - > _m2m_table - >游戏(通过UserProfile.games_liked)
  • User -> _m2m_table -> Games (by Games.likes)
  • 用户 - > _m2m_table - >游戏(由Games.likes提供)

You should remove one field.

你应该删除一个字段。

Django creates shortcuts to get access to relation from opposite side. That is what related_name stands for. So for your Game model, use have access to users by game.likes, and from user you have access to games by user.likes, b/c you have declared related_name='likes'

Django创建了快捷方式,以便从对方访问关系。这就是related_name所代表的含义。因此,对于您的游戏模型,使用可以通过game.likes访问用户,并且可以通过user.likes访问用户,b / c您已声明related_name ='likes'