zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    结合源码浅析Struts2与Spring整合的原理
    LINUX centOS6.x下安装redis
    基于Spring注解@cacheable 集成redis
    windows下搭建LDAP并利用Java实现对LDAP的操作
    Java利用freemaker和(excelXML表格或wordXML表格),导出自己任何想要格式的文档
    创建oracle表的时候一个小细节,会导致你处理java类型转换是时候很麻烦
    socketlog的安装和使用
    Windows 定时任务对数据库进行操作
    将博客搬至CSDN
    git+gitlab实现git版本控制管理本地化+自动化部署
  • 原文地址:https://www.cnblogs.com/surpass123/p/13033933.html
Copyright © 2011-2022 走看看