数据库
首页 > 数据库> > day66---数据库的三大范式、数据库查询优化、事务的四大特性

day66---数据库的三大范式、数据库查询优化、事务的四大特性

作者:互联网

聚合查询aggregate()

聚合函数aggregate()是QuerySet一个终止语句,它返回了一个包含一系列键值对的字典,键的名称是聚合值的标识符(默认是由字段和聚合函数名称自动生成,也可以指定键的名称),值是计算出来的聚合值。

from django.db.models import Max,Min,Avg,Count,Sum
from app01 import models

models.Book.objects.aggregate(
    min_price=Min(price),
    max_price=Max(price),
    sum_price=Sum(price),
    avg_price=Avg(price),
    count_num=Count(pk),
)

分组查询annotate

数据库在严格模式下,分组查询只能取到分组的依据,而取不到组内的其它字段。
SET sql_mode = "ONLY_FULL_GROUP_BY";

models.Book.objects.annotate()  # models后面点什么就是按什么分组

如果需要按照指定的字段分组,则:
models.Book.objects.values('字段').annotate() # value出现在annotate前面,那么则按照括号的字段进行分组。

F查询与Q查询

"""
F查询:如果查询条件是两个字段比较的结果,那么你需要用到F查询
Q查询:如果查询条件中含有"&",“|”,“not”,则需要使用Q查询
"""
# 用法:
from django.db.models import F,Q
from app01 import models

# 查询出卖出大于库存的书籍
res = models.Book.objects.filter(sell_out__gt=F('stock'))

# 将所有书的名字后面加上爆款
from django.db.models import Value
from django.db.models.functions import Concat

models.Book.objects.update(name=Concat(F('name'),Value('爆款')))

# 查询出价格大于600或者库存小于100的书籍
res = models.Book.obejects.filter(Q(price__gt=600)|Q(sell_out__lt=100))

Q对象的高阶用法  字符串的形式
q=Q()  #空对象
q.connector = 'or' #更改对象之间的默认连接关系,默认为and
q.children.append(('price__gt',600)) # 增加查询条件
q.children.append(('sell_out__lt',100))
models.Book.objects.filter(q) # filter内可以直接放多个Q对象,默认是and关系连接

ORM事务

"""
事务的四大特性(ACID):
(1)原子性:事务中的所有操作都是不可分割的原子单元。事务中的操作要么都成功,要么都失败。
(2)一致性:事务必须使得数据库从一个一致性状态,变成另外一个一致性状态。
(3)隔离性:事务的操作是相互互不干扰的,多个并发事务的操作是相互隔离的。
(4)持久性:事务一旦提交了,那么对于数据库的更改是永久性的。
"""

from django.db import transaction
try:
  with transaction.atomic():
    pass
    # with代码块里面所有的orm操作都属于同一个事务
except Exception as e:
  	print(e)

数据库查询优化

"""
only和defer:
only:将括号字段的属性值封装到返回的对象中,点改字段不需要再走数据库查询,点其他字段需要频繁的查询数据库。
defer:与defer相反,将除了括号内之外的属性值封装到返回的对象中,点其他字段不需要走数据库查询,点括号内的字段会频繁的走数据库查询。
"""

"""
select_related和prefetch_related:
select_related:它的内部本质是联表操作(inner join),将连表之后的查询结果全部封装到对象中,之后对象在点击表的字段的时候都无需再走数据库。
注意:括号内只能放外键字段,且多对多不行,括号内可以放多个外键字段。

prefetch_related:它的内部本质是子查询,通过子查询的方式,将多张表的数据封装到对象中。

"""

今日内容

数据库设计的三大范式

设计范式的目的:

"""
为了建立冗余较小、结构合理的数据库,设计数据库时候要遵循一定的规则。在关系型数据库中这种规则被称为范式。
"""

在实际的开发过程中,最为常见的范式有三个。

第一范式(1NF)

第一范式是最基本的范式。

定义:如果数据库表中的每个字段的属性值都是不分解的原子项,那么该数据表就满足第一范式(1NF)。

"""
简单来说,表中字段的属性值都是原子项的,不可以再进行分割。
"""
1NF是关系模式应具备的最起码的条件,如果数据库设计不能满足第一范式,就不称为关系型数据库。关系数据库设计研究的关系规范化是在1NF之上进行的。

如下表:

学生的编号 姓名 性别 联系方式
20168804 姜春 18374609478,220435@qq.com
20178812 李乾新 13733160788,330435@qq.com

上述的表就不满足第一范式,联系方式字段还可以再分,可以分为如下:

学生的编号 姓名 性别 手机 邮箱
20168804 姜春 18374609478 220435@qq.com
20178812 李乾新 13733160788 330435@qq.com

第二范式(2NF)

第二范式在第一范式的基础之上更进一层。第二范式要确保数据库表中的每一列都与主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。

也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

比如学生选课表:

学生 课程 教师 教室 教材 上课时间
姜春 python jason 301 《python基础》 08:00
李乾新 go egon 302 《go从入门到放弃》 14:30

这里通过(学生,课程)可以确定教师、教材,教室和上课时间,所以可以把(学生,课程)作为联合主键。但是,教材并不完全依赖于(学生,课程),只拿出课程就可以确定教材,因为一个课程,一定指定了某个教材。这就叫不完全相关,或者部分相关。出现这种情况,就不满足第二范式。

修改后,选课表:

学生 课程 教师 教室 上课时间
姜春 python jason 301 08:00
李乾新 go egon 302 14:30

课程表:

课程 教材
python 《python基础》
go 《go从入门到放弃》

所以,第二范式可以说是消除部分依赖。第二范式可以减少插入异常,删除异常和修改异常。

第三范式(3NF)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

举个例子,比如上述的学生选课表,你将教师,以及教师职称放入改表中是不合适的,教师依赖于(学生,课程),而教师职称依赖于教师,这叫传递依赖,不满足第三范式。

总结

"""
第一范式就是原子性,字段不可再分割;
第二范式就是完全依赖,没有部分依赖;
第三范式就是没有传递依赖。
"""

参考博客:

https://www.iteye.com/blog/aijuans-1629645

https://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.html

https://www.cnblogs.com/zhhh/archive/2011/04/21/2023355.html

标签:范式,models,数据库,查询,Book,day66,price,三大
来源: https://www.cnblogs.com/surpass123/p/13033933.html