• 关系型数据库基础总结


    关系型数据库架构

    整体思维架构

    架构

    • 如何设计一个关系型数据库

      1、需要一个文件存储系统(RDBMS)
      2、需要一个程序实例(对存储系统进行逻辑管理)
      包括:存储管理、缓存机制、SQL解析、日志管理、权限划分、容灾机制、索引管理、锁管理
      

    索 引

    • 为什么要使用索引
    快速查询数据
    
    • 什么样的信息能成为索引
    主键、唯一键以及普通键等
    
    • 索引的数据结构

      1、生成索引,建立二叉查找树进行二分查找
      2、生成索引,建立B-Tree结构进行查找
      3、生成索引,建立B+-Tree结构进行查找
      4、生成索引,建立Hash结构进行查找
      

      B-Tree定义:

      1、根节点至少包括两个孩子

      2、树种每个节点最多含有m个孩子(m>=2)

      3、除根节点和叶节点外,其他每个节点至少有ceil(m/2)(取上限)个孩子

      4、所有叶子节点都位于同一层

      5、

      B+-树的定义

      1、非叶子节点的子树指针与关键字个数相同

      2、非叶子节点的子树P[i],指向关键字值[K[i],K[i+1]]的子树

      3、非叶子节点仅用来索引,数据都保存在子节点中

      4、所有叶子节点均 有一个链指针指向下一个叶子节点

      hash索引的缺点:

      1、仅仅能满足 “=”,“in”,不能使用范围查询

      2、无法被用来避免数据的排序操作

      3、不能利用部分索引键查询

      4、不能避免表扫描

      5、遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高

      BitMap索引:

      很少数据库支持BIgMap索引

      结论:
      1、B+树的磁盘读写代价更低
      2、B+树的查询效率更加稳定
      3、B+树更有利于对数据库的扫描
      
    • 密集索引和稀疏索引的区别

    1、密集索引文件中的每个搜索码值都对应一个索引值
    
    2、稀疏索引文件只为索引码的某些值建立索引项 
    

    InnoDB:

    1、若一个主键被定义,该主键则作为密集索引;

    2、若没有主键被定义,该表的第一个唯一非空索引则作为密集索引

    3、若不满足以上条件,innodb内部会生成一个隐藏主键(密集索引)

    4、非主键索引存储相关键位和其对应的主键值,包含两次查找

    • 如何定位并优化慢查询Sql

      • 根据慢日志定位慢查询sql

        show variable like '%quer%'   #查询数据库相关变量
        'slow_query_log' ——查看是否打开了慢日志查询功能;
        ‘slow_query_log_file’ ——慢查询日志的存放位置;
        ‘long_query_time’ ——多长时间的查询被定义为慢查询,单位为 秒;
        
        show status like '%slow_queries%';  #查看有多少慢sql
        
      • 使用explain等工具分析sql

        explain + sql ;
        

        explain关键字段:

        1、type:

        system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_sunquery>index_subquery>range>index>all 最后两个是 index和all 表示是全表扫描,sql需要优化;

        2、extra:

        当该字段出现以下2项以为着mysql根本不能使用索引,效率会受到重大影响,应尽可能对此进行优化。

        • Using filesort:表示mysql会对结果使用一个外部索引排序,而不是从表里按索引次序读到相关内容。可能在内存或者磁盘上进行排序。mysql中无法利用索引完成的排序操作称为“文件排序
        • Using temporary:表示mysql在对查询结果排序时使用临时表。常见于排序order by 和分组查询 group by。
      • 修改sql或者尽量让sql走索引

    • 联合索引的最左匹配原则成因

    1、最左匹配原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a=3 and b=4 and c>5 and d=6 如果建立(a、b、c、d)顺序的索引,d是用不到索引的,如果建立(a、b、d、c)的索引则都可以用到,a、b、d的顺序可以任意调整。
    
    2、=和in 可以乱序,比如a=1 and b=2 and c=3建立(a,b,c)索引可以任意顺序,mysql的查询优化器会自动优化。
    

    成因:

    mysql 会对联合索引从左到右 先后执行 order by col1(第一个字段)、col2(第二个字段),所以直接上来使用第二个字段无法使用索引

    • 索引是建立得越多越好吗

      1、数据量小的表不需要建立索引,建立会增加额外的索引开销
      2、数据变更需要维护索引,因此更多的索引以为着更多的维护成本
      3、更多的索引意味着也需要更多的空间
      

    数据库锁的分类

    1、按锁的粒度分类:表级锁、行级锁、页级锁

    2、按锁级别划分:共享锁、排它锁

    3、按锁的方式划分:自动锁、显式锁

    4、按操作划分,可分为DML锁,DDL锁

    5、按使用方式划分,可分为乐观锁、悲观锁

    MyISAM与InnoDB关于锁方面的区别是什么

    • MyISAM默认用的是表级锁,不支持行级锁;

      适合场景:
      1、频繁执行全表count语句
      2、对数据进行增删改的频率不高,查询非常频繁
      3、没有事务
      
    • InnoDB默认用的是行级锁,也支持表级锁;

      1、数据增删改查都相当频繁
      2、可靠性要求比较高,要求支持事务
      
    共享锁(对数据库表的读操作)

    在并发情况下,如果对一张表(记录)加了共享锁的情况下,其他session可以继续加共享锁;

    在并发情况下,如果对一张表(记录)加了排他锁,无论共享锁和排他锁都无法再加;

    排它锁(对数据库表的写操作)

    在并发情况下,如果对一张表(记录)加了共享锁的情况下,无论共享锁和排他锁都无法再加;

    在并发情况下,如果对一张表(记录)加了排他锁的情况下,无论共享锁和排他锁都无法再加;

    InnoDB查询语句在走索引的时候,是行级锁以及gap锁
    InnoDB查询语句在不走索引的时候,是表级锁
    关闭mysql InnoDB的自动提交事务功能;
    set autocommit = 0 #关闭自动提交;
    手动加共享锁:select xxxx lock in share mode;

    数据库事务的四大特性

    • 原子性

    • 一致性

    • 隔离性

    • 持久性

    事务隔离级别以及各级别下的并发访问问题

    1、更新丢失(我和别人同时开启事务,自己在更新表数据进行提交时,覆盖了别人比我先提交的更新)——mysql所有事务隔离级别在数据库层面上均可避免

    2、脏读(读到了别人没有提交的数据)——read-committed事务隔离级别以上可避免

    3、不可重复读(第一次读和第二次读由于别人提交了一个事务,导致我前后读取同一个数据不一致)——repaeatabe-read事务隔离级别以上可避免

    4、幻读(第一次读和第二次读由于别人提交了一个事务,导致我前后读取的数据条数不一致)——serializable事务隔离级别可避免

    oracle默认事务级别是:read-commit
    mysql默认事务级别是:repeatable-read
    查看数据库的隔离级别:
    select @@tx_isolation;
    

    设置隔离级别等级:

    set session transaction isolation level read uncommitted;
    

    注意:与 SQL 标准不同的地方在于InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock 锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要求,即达到了 SQL标准的SERIALIZABLE(可串行化)隔离级别。

    InnoDB可重复读隔离级别下如何避免幻读

    表象:快照读(非阻塞)——伪MVCC

    当前读(加了锁的增删改查):

    select .... lock in share mode;
    
    select ...for update;
    
    update,delete,insert
    

    快照读(不加锁的非阻塞读):

    select ...
    

    内在:next-key锁(行锁+gap锁

    • 对主键索引或者唯一索引会用Gap锁吗
      • 如果where条件全部命中,则不会用Gap锁,只会加记录锁;
      • 如果where条件部分命中或者全不命中,则会加Gap锁;
    • Gap锁会用在非唯一索引或者不走索引的当前读中;

    笔记:gap就是间隙锁,就是在对表某几行进行操作的时候,为了防止出现幻读(我在未提交事务的时候,别人对表进行了删除和插操作),会在命中条件的几个行的间隙行区间里加上锁,别人无法进行删除插入操作。

    RC、RR级别下的InnoDB的非阻塞读(快照读)如何实现

    1、数据行里DB_TRX_ID(事务标识符),DB_ROLL_PTR ,DB_ROW_ID字段 ;

    2、undo日志

    3、 read view

    语法

    group by分组

    ​ - 满足select子句中的列名必须为分组列或者函数

    ​ - 列函数对于group by 子句定义的每个组各返回一个结果

    having

    统计相关:count,sum,max,min....

    理论范式

  • 相关阅读:
    Docker——WIN7 安装 Docker实战与入门
    TensorFlow——dropout和正则化的相关方法
    TensorFlow——学习率衰减的使用方法
    TensorFlow——MNIST手写数据集
    TensorFlow——分布式的TensorFlow运行环境
    类加载器
    死亡的对象
    spring boot整合kafka
    Java验证手机号
    类生命周期
  • 原文地址:https://www.cnblogs.com/xujie09/p/11595589.html
Copyright © 2020-2023  润新知