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