当前位置:Gxlcms > 数据库问题 > orm常用字段和数据库优化查询

orm常用字段和数据库优化查询

时间:2021-07-01 10:21:17 帮助过:2人阅读

可以重写表名。

# index_together  联合索引。

# unique_together  联合唯一索引。

# ordering  指定默认按什么字段排序。

只有设置了该属性,我们查询到的结果才可以被reverse()。

技术图片  
 class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)

        class Meta:
            # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
            db_table = "table_name"

            # 联合索引
            index_together = [
                ("pub_date", "deadline"),
            ]

            # 联合唯一索引
            unique_together = (("driver", "restaurant"),)
            
            ordering = (‘name‘,)
            
            # admin中显示的表名称
            verbose_name=‘哈哈‘

            # verbose_name加s
            verbose_name_plural=verbose_name
 

三、数据库优化查询

1.update()与save()的区别

两者都是对数据的修改保存操作,但是save()函数是将数据列的全部数据项全部重新写一遍,效率极低,比如book_obj.save()会将对象所有属性重新保存一次

而update()则是针对修改的项进行针对的更新效率高耗时少,比如,update(price),指哪打哪只会保存价格这一个属性

所以以后对数据的修改保存用update()

2.惰性查询

查询集 是惰性执行的 —— 创建查询集不会带来任何数据库的访问。你可以将过滤器保持一整天,直到查询集 需要求值时,Django 才会真正运行这个查询。

queryResult=models.Article.objects.all() # 只写这一句不会请求数据库
 
print(queryResult) # 直到你需要结果,此时才会查询数据库
 
for article in queryResult:
    print(article.title)    # 这样也会查询

orm内所有的语句操作 都是惰性查询:只会在你真正需要数据的时候才会走数据库,如果你单单只写orm语句时不会走数据库的
这样设计的好处 在于 减轻数据库的压力

3.only和defer 两对头

 

#only    only会将括号内的所有的字段信息 全部查询出来封装对象中

res = models.Book.objects.only(‘title‘)
            for r in res:
            # print(r.title)  # 只走一次数据库查询,将查询到的所有信息封装成一个对象,随后查询这些信息不需要再请求数据库,直接可以用点方法从对象中取出
              print(r.price)  
            # 当你点击一个不是only括号内指定的字段的时候 不会报错 而是会帮你去数据库查询,循环几次查几次,频繁的走数据库查询,当你有成千上万条信息时对数据库造成一万点伤害

#defer    defer会将不是括号内的所有的字段信息 全部查询出来封装对象中

 res1 = models.Book.objects.defer(‘title‘)  # defer与only是相反的
            for r in res1:  
            # print(r.title)# 查询括号内的字段,会频繁的走数据库查询
            print(r.price)#查询括号内没有的,只走一次

4. select_related 与 prefetch_related  两兄弟

res = models.Book.objects.all()
   for r in res:
      print(r.publish.name) #查询N次,这样是跨表查询,循环一次访问一次数据库,有一千万个书籍就查询一千万次

#常规的all方法,查询自己表里没有的属性,就需要跨表查询,虽然可以获取,但是你去查询一次就会访问一次数据库,查询其他表就不推荐这个了
#查询自己表里面有的属性时可以使用


#select_related  主动关联表

1. 主要针一对一和多对一关系进行优化。
2. 使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能
 

res = models.Book.objects.all().select_related(‘publish‘) for r in res: print(r.publish.name) #只查询一次,查询语句贼长包含两张表所有信息

技术图片

#1.select_related:会将FK表全部信息直接拿过来(可以一次性拿多张表)跟当前表所有信息拼接成一张大表,封装成一个对象 之后获取信息直接点方法获取,不需要再访问数据库从而降低你跨表查询 数据库的压力,但是速度会比较慢,活太多 #2.支持一次性拿多张表,如果当前表有多个外键,括号内用逗号链接
    如果FK1表中还有外键还可以再关联下去,用双下划线链接,最后将N张表合并成一个超级表     res = models.Book.objects.all().select_related(‘外键字段1__外键字段2__外键字段3__外键字段4......‘) #注意select_related括号只能放外键字段(一对一和一对多才行),res = models.Book.objects.all().select_related(‘authors‘)多对多的关系就会报错
 

# prefetch_related  不主动关联表

1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。
2. 优化方式是分别查询每个表,然后用Python处理他们之间的关系。
 

res = models.Book.objects.prefetch_related(‘publish‘) for r in res: print(r.publish.name) #只会走两次查询

技术图片
"""
不主动连表操作(但是内部给你的感觉像是连表操作了)  而是先将book表中所有的publish的id全部拿出来,再到Publish表中将id对应的所有的数据的所有信息全部取出

括号内有几个外键字段 就会走几次数据库查询操作    
"""

orm常用字段和数据库优化查询

标签:时间   friends   dea   过滤器   any   userinfo   ble   mysql数据库   将不   

人气教程排行