美文网首页
必知必会 - Mysql

必知必会 - Mysql

作者: 半山Light | 来源:发表于2020-09-21 15:03 被阅读0次

    存储引擎InnoDB

    InnoDB 底层存储结构为B+树, B树的每个节点对应innodb的一个page,page大小是固定的,一般设为 16k。其中非叶子节点只有键值,叶子节点包含完成数据。



    适用场景:
    1)经常更新的表,适合处理多重并发的更新请求。
    2)支持事务。
    3)可以从灾难中恢复(通过 bin-log 日志等)。
    4)外键约束。只有他支持外键。
    5)支持自动增加列属性 auto_increment。

    存储引擎TokuDB(Fractal Tree-节点带数据)

    TokuDB 底层存储结构为 Fractal Tree,Fractal Tree 的结构与 B+树有些类似, 在 Fractal Tree中,每一个 child 指针除了需要指向一个 child 节点外,还会带有一个 Message Buffer ,这个Message Buffer 是一个 FIFO 的队列,用来缓存更新操作。
    例如,一次插入操作只需要落在某节点的 Message Buffer 就可以马上返回了,并不需要搜索到叶子节点。这些缓存的更新会在查询时或后台异步合并应用到对应的节点中。



    TokuDB 在线添加索引,不影响读写操作, 非常快的写入性能, Fractal-tree 在事务实现上有优势。 他主要适用于访问频率不高的数据或历史数据归档。

    存储引擎MyIASM

    MyIASM是 MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当 INSERT(插入)或 UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。
    ISAM 执行读取操作的速度很快,而且不占用大量的内存和存储资源。在设计之初就预想数据组织成有固定长度的记录,按顺序存储的。---ISAM 是一种静态索引结构。
    缺点是它不支持事务处理。

    存储引擎Memory

    Memory(也叫 HEAP)堆内存:使用存在内存中的内容来创建表。每个 MEMORY 表只实际对应一个磁盘文件。MEMORY 类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH 索引。但是一旦服务关闭,表中的数据就会丢失掉。 Memory 同时支持散列索引和 B 树索引,B树索引可以使用部分查询和通配查询,也可以使用<,>和>=等操作符方便数据挖掘,散列索引相等的比较快但是对于范围的比较慢很多。

    数据库三范式

    1NF 列不可再拆分
    2NF 每个表只描述一件事
    3NF 不存在对非主键列的传递依赖

    索引

    索引(Index)是帮助 MySQL 高效获取数据的数据结构。常见的查询算法,顺序查找,二分查找,二叉排序树查找,哈希散列法,分块查找,平衡多路搜索树 B 树(B-tree)

    1.唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录
    2.为经常需要排序、分组和联合操作的字段建立索引
    3.为常作为查询条件的字段建立索引
    4.限制索引的数目: 越多的索引,会使更新表变得很浪费时间
    5.尽量使用数据量少的索引
    6.如果索引的值很长,那么查询的速度会受到影响
    7.如果索引字段的值很长,最好使用值的前缀来索引
    8.删除不再使用或者很少使用的索引
    9.最左前缀匹配原则,非常重要的原则
    10.尽量选择区分度高的列作为索引,区分度的公式是表示字段不重复的比例
    11.索引列不能参与计算,保持列“干净”:带函数的查询不参与索引
    12.尽量的扩展索引,不要新建索引
    13.索引不会包含有NULL值的列,所以我们在数据库设计时不要让字段默认值为NULL
    14.使用短索引:对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
    15.索引列排序:MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
    16.应尽量不使用不等操作:NOT IN、<>、!= 等操作
    17.应尽量避免在 where 子句中对字段进行 null 值判断、使用 or 或 union、in 和 not in 要慎用、 使用参数、使用表达式、函数操作、否则将导致引擎放弃使用索引而进行全表扫描
    18.一个表中的索引数最好不要超过6个,尽量使用数字型字段,字符型在比较时会逐个比较每一个字符

    数据库事务

    解释:一个不可分割的工作逻辑单元

    特性:
    A 原子性 (各步操作不可分,都执行或不执行)
    C 一致性(事务完成时,数据必须处于一致状态)
    I 隔离性(对数据进行修改的所有并发事务是彼此隔离的,独立的,不依赖影响其他事务)
    D 永久性(事务完成,事务日志能够保持事务的永久性)

    存储过程

    特定功能的SQL语句
    优化思路:
    1)尽量利用一些 sql 语句来替代一些小循环,例如聚合函数,求平均函数等
    2)中间结果存放于临时表,加索引。
    3)少使用游标。sql 是个集合语言,对于集合运算具有较高性能。而 cursors 是过程运算。比如对一个 100 万行的数据进行查询。游标需要读表 100 万次,而不使用游标则只需要少量几次读取。
    4)事务越短越好。sqlserver 支持并发操作。如果事务过多过长,或者隔离级别过高,都会造成并发操作的阻塞,死锁。导致查询极慢,cpu 占用率极地。
    5)使用 try-catch 处理错误异常。

    6)查找语句尽量不要放在循环内。

    触发器

    触发器是一段能自动执行的程序,是一种特殊的存储过程,触发器和普通的存储过程的区别是:
    触发器是当对某一个表进行操作时触发。诸如:update、insert、delete 这些操作的时候,系统会自动调用执行该表上对应的触发器。

    数据库并发策略

    乐观锁:(读数据的时候,别人不会去写自己所读的数据)

    悲观锁:(读数据的时候,别人可能刚好在写自己刚读的数据)
    分为排它锁(写锁)和共享锁(读锁)

    时间戳:(不加锁,通过时间戳来控制并发出现的问题)
    时间戳就是在数据库表中单独加一列时间戳,比如“TimeStamp”,每次读出来的时候,把该字段也读出来,当写回去的时候,把该字段加1,提交之前 ,跟数据库的该字段比较一次,如果比数据库的值大的话,就允许保存,否则不允许保存,这种处理方法虽然不使用数据库系统提供的锁机制,但是这种方法可以大大提高数据库处理的并发量

    数据库锁

    在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎)、表级锁(MYISAM引擎)和页级锁(BDB引擎 )。

    MySQL常用存储引擎的锁机制
    MyISAM和MEMORY采用表级锁(table-level locking)
    BDB采用页面锁(page-level locking)或表级锁,默认为页面锁
    InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

    摘自:https://www.jianshu.com/p/5ccfa9801ad3

    Redis分布式锁

    1.获取锁的时候,使用 setnx(SETNX key val:当且仅当 key 不存在时,set 一个 key为 val 的字符串,返回 1;若 key 存在,则什么都不做,返回 0)加锁,锁的 value
    值为一个随机生成的 UUID,在释放锁的时候进行判断。并使用 expire 命令为锁添
    加一个超时时间,超过该时间则自动释放锁。
    2.获取锁的时候调用 setnx,如果返回 0,则该锁正在被别人使用,返回 1 则成功获取
    锁。 还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
    3.释放锁的时候,通过 UUID 判断是不是该锁,若是该锁,则执行 delete 进行锁释放。

    分库分表

    分库分表有垂直切分和水平切分

    垂直切分(按照功能模块): 将表按照功能模块、关系密切程度划分出来,部署到不同的库上。例如,我们会建立定义数据库 workDB、商品数据库 payDB、用户数据库 userDB、日志数据库 logDB 等,分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。

    水平切分(按照规则划分存储): 当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,例如 userID 散列,进行
    划分,然后存储到多个结构相同的表,和不同的库上。

    两阶段提交协议

    分布式事务是指会涉及到操作多个数据库的事务,在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调。
    XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。 XA 接口函数由数据库厂商提供。
    二阶段提交(Two-phaseCommit)是指,在计算机网络以及数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法(Algorithm)。通常,二阶段提交也被称为是一种协议(Protocol))。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的 ACID 特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。 因此,二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。

    准备阶段:协调者给每个参与者发送prepare消息->失败或执行事务(写本地redo和undo日志,但不提交)
    提交阶段: 协调者收到参与者的失败或超时消息->返回rollback消息,否则,发送commit消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源(必须在最后阶段释放资源)

    缺点:
    同步阻塞问题 - 执行过程中,所有参与节点都是事务阻塞型的
    单点故障 - 由于协调者的重要性,一旦协调者发生故障,参与者会一直阻塞下去
    数据不一致(脑裂现象) - 在二阶段提交过程中,协调者发送commit消息后网络异常或协调者故障等,导致一部分参与者接受到commit消息,回导致整个分布式系统出现数据不一致现象
    二阶段无法解决的问题(数据状态不确定) - 协调者在发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了,那么即使协调者选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否已经被提交

    三阶段提交协议

    二阶段提交(2PC)的改进版本。
    与两阶段提交不同的是,三阶段提交有两个改动点。
    1、引入超时机制。同时在协调者和参与者中都引入超时机制。
    2、在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是
    一致的。也就是说,除了引入超时机制之外,3PC 把 2PC 的准备阶段再次一分为二,这样三阶段
    提交就有 CanCommit、PreCommit、DoCommit 三个阶段。

    CanCommit 阶段
    协调者向参与者发送 commit 请求,参与者如果可以提交就返回 Yes 响应,否则返回 No 响应。

    PreCommit 阶段
    协调者根据参与者的反应情况来决定是否可以继续进行,有以下两种可能。假如协调者从所有的参与者获得的反馈都是 Yes 响应,那么就会执行事务的预执行假如有任何一个参与者向协调者发送了 No 响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。

    doCommit 阶段
    该阶段进行真正的事务提交,主要包含 1.协调者发送提交请求 2.参与者提交事务 3.参与者响应反馈( 事务提交完之后,向协调者发送 Ack 响应。)4.协调者确定完成事务。

    CAP理论

    CAP 原则又称 CAP 定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
    1.一致性(C):
    在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
    2.可用性(A):
    在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
    3.分区容忍性(P):(必须的)
    以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在 C 和 A 之间做出选择。

    BASE理论

    BASE:全称:Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)三个短语的缩写,来自 ebay 的架构师提出。

    Base 理论是对 CAP 中一致性和可用性权衡的结果,其来源于对大型互联网分布式实践的总结,是基于 CAP 定理逐步演化而来的。其核心思想是:

    既是无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

    摘自:https://www.jianshu.com/p/9cb2a6fa4e0e

    柔性事务

    在电商领域等互联网场景下,传统的事务在数据库性能和处理能力上都暴露出了瓶颈。在分布式领域基于 CAP 理论以及 BASE 理论,有人就提出了 柔性事务 的概念。CAP(一致性、可用性、分区容忍性)理论大家都理解很多次了,这里不再叙述。说一下 BASE 理论,它是在 CAP 理论的基础之上的延伸。包括 基本可用(Basically Available)、柔性状态(Soft State)、最终一致性(Eventual Consistency)。

    通常所说的柔性事务分为:两阶段型、补偿型、异步确保型、最大努力通知型 几种。

    两阶段型
    就是分布式事务两阶段提交,对应技术上的 XA、JTA/JTS。这是分布式环境下事务处理的典型模式。

    补偿型
    TCC 型事务(Try/Confirm/Cancel)可以归为补偿型。


    异步确保型
    通过将一系列同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步、阻塞操作的影响。


    最大努力通知型(多次尝试)
    这是分布式事务中要求最低的一种, 也可以通过消息中间件实现, 与前面异步确保型操作不
    同的一点是, 在消息由 MQ Server 投递到消费者之后, 允许在达到最大重试次数之后正常
    结束事务。

    SQL问题

    LEFT JOIN出现重复结果问题分析
    left join 语句格式为: A LEFT JOIN B ON 条件表达式
    left join 是以A表为基础,A表即左表,B表即右表。
    左表(A)的记录会全部显示,而右表(B)只会显示符合条件表达式的记录(期望1:1);
    如果在右表(B)中没有符合条件的记录,则右表记录不足的地方为NULL(1:0 );
    如果在右表(B)中有多条符合条件的记录,则左表会出现重复数据(1:N )

    • —— 定期更新有质量的知识点,欢迎跟踪

    相关文章

      网友评论

          本文标题:必知必会 - Mysql

          本文链接:https://www.haomeiwen.com/subject/oiyvyktx.html