Mysql进阶篇

1.Mysql服务架构

  • 连接层: 处理客户端连接请求,对用户进行认证

  • 服务层: 可以接收sql,调用存储过程,优化sql,缓存数据....

  • 引擎层: 负责实际与文件层进行交互操作的,可以有不同的引擎选择.

  • 物理文件层: 存储表数据 以及 各种日志文件.

2.Mysql引擎

存储引擎就是存储数据,建立索引、更新 / 查询数据等技术的实现方式。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能

InnoDB

mysql的默认存储引擎,支持事务处理,有外键约束,支持索引,支持缓存,支持行级锁,遵循ACID原则

  • 每个表都会对应一个表空间文件,用来存储表的结构信息,生成一个ibd文件

MyISAM

MyISAM 是 MySQL 早期的存储引擎。不支持事务,不支持行级锁,只有表锁而且并发量小,不支持外键但支持全局索引

  • myisam的一张表在磁盘中存储文件有以下三个:.sdi存储表结构,.myd存储数据,.myi存储索引

Memory

表数据存放在内存中,Memory 的一张表在磁盘中的存储文件只有:xxx.sdi,用来存储表结构文件。和 MyISAM 引擎相比,没有了存储数据和索引的文件,因为他们在 Memory 中都被存储在内存中了。

总结对比

事务:MyISAM不支持。InnoDB支持

锁级别:MyISAM只支持表级锁,InnoDB支持行级锁和表级锁,默认使用行级锁,但是行锁只有通过索引查询数据才会使用,否则将使用表锁。

主键和外键:MyISAM 允许没有任何索引和主键的表存在,不支持外键。InnoDB的主键不能为空且支持主键自增长,如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键,支持外键完整性约束

存储结构:innodb数据和索引都放在表空间中,所有的表都保存在同一个数据文件中,innodb的表大小只受限于操作系统文件的大小,一般为2GB

使用场景:如果需要支持回滚事务,崩溃恢复能力的ACID事务,并要求实现行级锁并发控制,选择innodb。

如果数据表主要用来查询记录,读操作远多于写操作时且不需要使用事务,可以选择MyISAM,但在8.0以后该引擎已经被废除

3.数据库范式

第一范式(1NF):指表的列不可再分,数据库中表的每一列都是不可分割的基本数据项,同一列中不能有多个值; 第二范式(2NF):在 1NF 的基础上,还包含两部分的内容:一是表必须有一个主键;二是表中非主键列必须完全依赖于主键,不能只依赖于主键的一部分; 第三范式(3NF):在 2NF 的基础上,消除非主键列对主键的传递依赖,非主键列必须直接依赖于主键。 BC范式(BCNF):在 3NF 的基础上,消除主属性对于码部分的传递依赖

4.数据库索引

索引的本质就是一种通过减少查询需要遍历行数,依次来提升搜索效率的数据结构,避免了数据库的全表扫描,就好比书的目录,让你能更快的定位所需内容(一个表最多支持16个索引)

索引优缺点

优点

  1. 减少了遍历的行数,增加了搜索效率

  2. 通过索引对数据进行排序,降低了数据排序的成本,降低CPU的消耗

缺点

  1. 创建索引需要占用内存空间

  2. 对数据进行增删改时,索引树需要进行更新,需要一定的时间

  3. 在某些场景下会出现索引失效的场景

使用场景

建议添加的情况

  1. 在主键上添加索引,强制该列的唯一性

  2. 外键上添加索引,提高链接速度

  3. 在where子句上加,加快条件的判断速度

  4. 按范围存取的列或者在group by或order by中使用的列,因为索引已经排序,这样可以利用索引加快排序查询时间。

不建议添加的情况

  1. 区分度不高的列,例如性别,结果集占据了表中数据行的很大比例,这样并不能增加判断速度

  2. 频繁增删改的表,因为索引树的结构也需要一直改变

  3. 表数据过少的列

5.索引的分类

主键索引

为主键生成一个索引,不允许有空值

单值索引

即一个索引只包含单个列,一个表可以有多个单列索引

唯一索引

索引列的值必须唯一,允许为 nul

组合索引

把多个列打包,创建一个索引,降低了空间开销, 例如几个查询条件经常组合使用.

最左前缀原则

在使用组合索引的列作为条件时,必须要出现最左侧列为条件

全文索引

需要模糊查询时,一般的索引会失效,此时需要创建全文索引

 CREATE FULLTEXT INDEX 索引名 ON 表名(字段名) WITH PARSER ngram

聚簇索引和非聚簇索引

聚簇索引:更新聚簇索引列上的数据时,往往导致表中记录的物理顺序的变更,找到索引就相当于找到了数据,例如innodb中的主键索引

非聚簇索引:索引的存储和数据的存储是分离的,也就是说找到了索引但没找到数据,需要根据索引上的值(主键)再次回表查询,所谓回表查询就是先定位主键,再定位行记录

回表查询优化

索引覆盖:把所有需要查询的字段都放到普通索引中,这样普通索引查到的叶子结点中已经能够得到所需的所有字段

  1. 减少查询的字段,只查带有索引的字段,例如我们只查询主键id

  2. 修改表的索引,增加需要的字段例如查询user表时,把name也加到索引里,实现组合索引

6.索引的实现原理

常见的索引结构有B+树,hash索引

hash索引

mysql中只有memory引擎支持hash索引,查询效率很高可以实现一次定位

缺点

  1. 仅能满足等值查询,不支持范围搜索和排序

  2. 会发生哈希碰撞,只要发生碰撞就会出现全表扫描

B+树

优点

  1. 页内结点不存储数据,每次IO可以读取更多的行,减少IO读取次数

  2. 带顺序访问指针,所有的索引数据都存储在叶子节点,每个叶子结点都有指向相邻结叶子结点的指针,提高区间访问效率

7.事务

将多组sql放在一起执行,要么全部成功,要么全部失败

事务特性:ACID

  • 原子性:事务是一个不可分割的部分,要么都成功,要么都失败

  • 持久性:一旦事务提交后,对数据库的修改是永久的

  • 隔离性:事务在操作时,对其他事务的可见程度

  • 一致性:保证数据的完整可靠

8.事务并发问题

  1. 脏读:读取到了别人未提交的数据

  2. 不可重复读:在进行修改操作后,对同一事务两次读取的结果不相同

  3. 幻读:在进行新增或删除操作后,数据量发生改变

9.事务隔离级别

读未提交

一个事务可以读到另一个事务未提交的修改,会造成脏读,不可重复读,幻读

读已提交

一个事务只能读取另一个事务提交后的内容,解决了脏读问题,但没有解决不可重复度,幻读

可重复读

一个事务在同一个读操作中,即使别的事务修改了这个事务读取同一个数据源应该相同

串行化

事务只能一个一个进行,读写阻塞

10.事务实现原理

原子性实现

使用了undolog日志,记录了增删改的反方向操作,当事务想要回滚时,利用undolog中的信息进行恢复

持久性

依靠rodolog实现,在执行时会保存已经执行的sql语句到redolog日志中,为了提高效率,会在写入redolog之前会先写入到内存中的redo log buffer缓存区中,redo log buffer中修改的数据会定期刷新到磁盘的redo log文件中

隔离性(读已提交/可重复读)

innodb的隔离级别由MVCC和锁机制来实现

MVCC:多版本并发控制,是innodb引擎实现事务隔离级别的一种具体实现方式,每次事务对某条数据进行操作时,会生成一个版本链,如果是读已提交那么就会每次从版本链上生成一个快照,再次读取时,读取的就是最新数据,可重复读读取的就是之前版本的快照,实现读取驶距的一致性,也成为快照读

锁机制:事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁

11.mysql锁机制

按照粒度分为:表锁,行锁,页锁,间隙锁

  1. 表锁:对整张表加锁,实现简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。但是并发度一般

  2. 行级锁:对索引项进行加锁,不是对记录加锁,只有通过索引检索数据时,innodb才能使用行锁,负责就会使用表锁,锁的粒度小,但是访问不同行数据使用相同的索引键就会发生冲突

  3. 页锁:颗粒度介于行级锁定与表级锁之间,并发能力也介于二者之间

  4. 间隙锁:获取某个范围区间,表table中有id值为1,2,4,5的数据。

1.事务1在执行:select * from table where id >= 1 and id <= 5;(此时事务1为id值1~5的数据加了锁,包括不存在的id=3的行,对3来说就是间隙锁) 2.那么事务2在执行:insert操作插入id值为3的数据时,就需要等待事务1提交完成; 否则会造成事务1的幻读(即2次读取结果不同)。 3.如果id=3的记录存在就不会使用间隙锁(此时where条件全部命中),只会使用记录锁。

行级锁又分为:共享锁和排他锁

  1. 共享锁:其他的事务可以进行读操作,但会阻塞写操作,只有读锁释放后,才能执行写操作

  2. 排他锁:一个事务获取排它锁之后,可以对锁定范围内的数据行执行写操作,在锁定期间,其他事务不能再获取这部分数据行的锁(共享锁、排它锁),只允许获取到排它锁的事务进行更新数据。

12.mysql日志

binlog:二进制日志是 Server 层生成的日志,主要用于数据备份和主从复制;记录了DML和DDL语句,不记录查询语句

redolog:重做日志是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢复

undolog:回滚日志是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC

重做日志

在一条语句进行执行的时候,InnoDB 引擎会把新记录写到 redo log 日志中,然后更新内存,更新完成后就算是语句执行完了,然后在空闲的时候或者是按照设定的更新策略将 redo log 中的内容更新到磁盘中。

重做日志两部分组成:

一是内存中的重做日志缓冲(redo log buffer),是易失的;

二是重做日志文件(redo log file),是持久的。redo log 记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。

回滚日志

两个作用:提供回滚和MVCC

undo log 和 redo log 记录物理日志不一样,它是逻辑日志。可以认为当 delete 一条记录时,undo log 中会记录一条对应的 insert 记录,反之亦然,当 update 一条记录时,它记录一条对应相反的 update 记录。

二进制日志

binlog,记录了所有的DML和DDL语句,但不记录查询语句,MySQL的主从复制, 就是通过该binlog实现的

statement:记录sql语句

row:记录每一行的数据变更

mixed:一般的复制使用STATEMENT 模式保存 binlog ,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 binlog。

错误日志

用来记录 MySQL 服务器运行过程中的错误信息,默认开启无法关闭.复制环境下,从服务器进程的信息也会被记录进错误日志

查询日志

查询日志里面记录了数据库执行的所有命令,不管语句是否正确,都会被记录,默认是关闭的。

慢查询日志

它用来记录在MySQL中响应时间超过阀值的SQL语句,具体是指运行时间超过 long_query_time 值的SQL,这样的SQL则会被记录到慢查询日志中。long_query_time 的默认值为10,意思是运行10S以上的SQL语句。

13.主从复制

是指将主数据的DDL和DML操作进行二进制日志传送到从库服务器中,然后再从库中对这些日志进行重新执行,从而使得从库和主库保持同步

  1. 主库出现问题,快速切换到从库

  2. 实现读写分离

  3. 在从库执行备份,避免影响主库操作

原理

  1. 主库执行完sql后,生成binlog日志

  2. slave通过IOThread读取并且返回binlog的内容,并写入从库中生成一份自己的日志relaylog(中继日志)

  3. sqlThread会读取relaylog将他同步到从库的数据库中

14.分库分表

问题分析:数据过多时,磁盘空间不足

拆分策略:垂直拆分,水平拆分

垂直拆分

  1. 垂直分表:将一个表按照字段分成多个表,每个表存储一部分字段,将常用字段放在一个表中,不常用的放在另一个表中

  2. 垂直分库:以表为依据,按照业务模块的不同,不同表拆分到不同库中,降低耦合

水平拆分

  1. 水平分表:将表结构的数据拆分,表数据的并集是全部数据

  2. 水平分库:每个库的表结构一致,但数据不一致,所有库的并集是全部数据

实现技术

  1. shardingJDBC:基于AOP原理,在本地执行的sql进行拦截,只支持Java语言

  2. MyCat:中间件

分库分表后ID键的处理

  1. UUID

  2. Redis生成ID

  3. 雪花算法

15.读写分离

解决数据库的写操作印象了查询的效率,适用于读远大于写的场景,基于主从复制

  1. 基于代理的方式:添加代理层应用对数据库的请求,根据不同请求类型转发到不同的库中

  2. 基于AOP进行拦截dao层的方法,动态切换主从数据源

  3. 基于中间件(MyCat)

16.mysql性能优化

  1. 查询sqk是尽量少使用select*

  2. 使用数值代替字符串类型:男0女1

  3. 使用varchar代替char

  4. 清表是优先使用truncate

  5. 使用explain分析sql执行计划

通过explain关键字知道MySQL是如何执行SQL查询语句的,分析select 语句的性能瓶颈,从而改进我们的查询,explain的结果如下

主要字段:

  1. id:sql执行顺序的标识,id越大优先级越高

  2. select_type:表示查询的类型(普通,子查询,关联查询)

  3. possible_keys:预期使用的索引可以有多个

  4. key:实际使用的索引,如果为null代表没有使用或索引失效

17.索引失效情况

  1. 在使用组合索引时没有遵循最左前缀原则

  2. 模糊查询导致失效

  3. 主键插入顺序不当导致页面分裂

     4. 类型转换

     5.“不等于”导致失效因为,“不等于”不能精准匹配,全表扫描二级索引树再回表效率不如直接全表扫描聚簇索引树,加在一起大的效率不如全表扫描

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/359536.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TSINGSEE青犀视频智慧电梯管理平台,执行精准管理、提升乘梯安全

一、方案背景 随着城市化进程的不断加快&#xff0c;我国已经成为全球最大的电梯生产和消费市场&#xff0c;电梯也成为人们日常生活中不可或缺的一部分。随着电梯数量的激增&#xff0c;电梯老龄化&#xff0c;维保数据不透明&#xff0c;物业管理成本高&#xff0c;政府监管…

StarRocks-3.1.0 单节点部署

1. 相关环境准备 FE&#xff1a; /opt/starrocks BE&#xff1a; /opt/starrocks 安装包下载 wget https://releases.starrocks.io/starrocks/StarRocks-3.1.0.tar.gz解压缩 tar -zxvf StarRocks-3.1.0.tar.gz 安装jdk (v2.5 及以上版本建议安装 JDK 11&#xff0c;我们使用…

腾讯mini项目总结-指标监控服务重构

项目概述 本项目的背景是&#xff0c;当前企业内部使用的指标监控服务的方案的成本很高&#xff0c;无法符合用户的需求&#xff0c;于是需要调研并对比测试市面上比较热门的几款开源的监控方案&#xff08;选择了通用的OpenTelemetry协议&#xff1a;Signoz&#xff0c;otel-…

MedSAM:深度学习通用医学影像分割模型,更快、更准确地自动识别诊断疾病

MedSAM是一款基于深度学习的医学影像分割工具&#xff0c;它能够自动识别和描绘医学影像中的重要区域&#xff0c;如肿瘤或其他组织的病变。该工具通过学习大量医学影像和对应的掩模&#xff08;即正确的分割结果&#xff09;&#xff0c;能够处理各种不同的医学影像和复杂情况…

数据库之TiDB基础讲解

文章目录 1 TiDB1.1 引言1.2 TiDB介绍1.3 系统架构1.3.1 TIDB Server1.3.2 PD Server1.3.3 TIKV Server1.3.4 TiKV如何不丢失数据1.3.5 分布式事务支持 1.4 与MySQL的对比1.5 性能测试1.5.1 测试一1.5.2 系统测试报告 2 1 TiDB 1.1 引言 当我们使用 Mysql 数据库到达一定量级…

使用nginx对视频、音频、图片等静态资源网址,加token签权

目前很多静态资源&#xff0c;都可以无权限验证&#xff0c;进行访问或转发&#xff0c;对有价值的资源进行签权&#xff0c;限制转发无法在代码中实现拦截&#xff0c;我们可以使用nginx对视频、音频、图片等静态资源网址&#xff0c;加token签权 如&#xff1a; http://192…

Win10 双网卡实现同时上内外网

因为需要同时上内网和外网&#xff0c;但公司做了网络隔离&#xff0c;不能同时上内外网&#xff0c;所以多加了块无线网卡&#xff0c;配置双网关实现同时上内外网&#xff0c;互不影响 打开 Windows PowerShell&#xff08;管理员&#xff09;&#xff0c;输入&#xff1a;ro…

CCF-CSP 202312-2 因子化简(Java、C++、Python)

文章目录 因子化简题目背景问题描述输入格式输出格式样例输入样例输出样例解释子任务 满分代码JavaCPython线性筛法 因子化简 题目背景 质数&#xff08;又称“素数”&#xff09;是指在大于 1 的自然数中&#xff0c;除了 1 和它本身以外不再有其他因数的自然数。 问题描述…

房屋租赁系统-java

思维导图&#xff1a;业务逻辑 类的存放&#xff1a; 工具类 Utility package study.houserent.util; import java.util.*; /***/ public class Utility {//静态属性。。。private static Scanner scanner new Scanner(System.in);/*** 功能&#xff1a;读取键盘输入的一个菜单…

DevOps落地笔记-02|影响地图:产品规划和需求分析的利器

从这一讲开始&#xff0c;我们进入 DevOps 正题。按照端到端的顺序&#xff0c;讲解 DevOps 中的最佳实践如何在软件开发过程中发挥作用。所谓端到端&#xff0c;是指从需求提出到需求被发布到生产环境交付给用户的整个过程&#xff0c;可以理解为软件开发的全生命周期。所谓最…

06 SB3之Thymeleaf实现视图返回

1快速尝试一个返回视图的项目 1.1创建器添加Web, Thymeleaf, lombok依赖创建项目 1.2 编写Controller Controller public class QuickController {RequestMapping("/exam/quick") public String quick(Model model){//业务处理结果数据&#xff0c;放入到 Model 模…

【lesson1】高并发内存池项目介绍

文章目录 这个项目做的是什么&#xff1f;这个项目的要求的知识储备和难度&#xff1f;什么是内存池池化技术内存池内存池主要解决的问题malloc 这个项目做的是什么&#xff1f; 当前项目是实现一个高并发的内存池&#xff0c;他的原型是google的一个开源项目tcmalloc&#xf…

万户 ezOFFICE SendFileCheckTemplateEdit.jsp SQL注入漏洞

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…

Redis内存设置

通过redis-cli进入Redis命令行 redis权限认证命令&#xff1a;auth 查看redis内存使用情况的命令&#xff1a;info memory 查看最大内存命令&#xff1a;config get maxmemory 设置最大内存命令&#xff1a;config set maxmemory 也可以通过redis.conf配置文件修改最大内存…

MicroPython核心:映射和字典

MicroPython字典和映射使用称为开放寻址和线性探测的技术&#xff0c;本文详细介绍了这两种方法。 开放寻址 开放寻址用于解决碰撞问题&#xff0c;碰撞是非常常见的现象&#xff0c;当两个条目恰好散列到同一个槽或位置时就会发生碰撞。例如&#xff0c;散列设置如下&#x…

计算机基础知识讲解(原码反码补码)(以及在C语言里面是如何计算和运用的)

补码反码掩码以及原理 补码、反码和掩码是计算机科学中用于表示和处理数值的三种编码方式。 原码 原码是最直观的数值表示方法&#xff0c;它将数值的二进制表示与其符号位结合起来。在原码表示中&#xff0c;正数的符号位为0&#xff0c;而负数的符号位为1。原码的缺点在于…

【pytorch】nn.linear 中为什么是y=xA^T+b

我记得读教材的时候是yWxb, 左乘矩阵W&#xff0c;这样才能表示线性变化。 但是pytorch中的nn.linear中&#xff0c;计算方式是yxA^Tb&#xff0c;其中A是权重矩阵。 为什么右乘也能表示线性变化操作呢&#xff1f;因为pytorch中&#xff0c;照顾到输入是多个样本一起算的&…

比Filebeat更强大的日志收集工具-Fluent bit的http插件实战

文章目录 1.前言2. fluent bit http插件配置以及参数详解3. Http 接口服务3.1 开发Http 接口服务3.2 重启fluent bit向http web服务发送数据 1.前言 Fluent Bit 的 HTTP 插件提供了一种灵活而通用的机制&#xff0c;可用于将日志数据 从各种环境中传输到指定的远程服务器&#…

C++_list

目录 一、模拟实现list 1、list的基本结构 2、迭代器封装 2.1 正向迭代器 2.2 反向迭代器 3、指定位置插入 4、指定位置删除 5、结语 前言&#xff1a; list是STL(标准模板库)中的八大容器之一&#xff0c;而STL属于C标准库的一部分&#xff0c;因此在C中可以直接使用…

TestNG中的DataProviders(@DataProvider annotation)

目录 什么是数据提供者&#xff1f; 数据提供程序及其返回的内容 DataProvider语法 DataProvider注释的方法可以返回什么&#xff1f; 使用数据提供程序的测试用例 如何在测试用例中使用数据提供程序&#xff1f; 其他类中的数据提供程序 在DataProvider带注释的方法中…