MySQL高级—尚硅谷—周阳—2018-03-28

视频链接

sql 优化 5 招:  (前 4 步,可拿下 99%)
    分析:观察,至少跑一天,看生产环境的 慢sql 情况。
    开启慢查询日志,设置阙值。比如超过 2 秒,就是慢sql,并将它抓取出来。
    explain +SQL 分析(出来八成了)
    进一步分析:show profile,查询 SQL 在 MYSQL 服务器里面的执行细节 和 生命周期情况。
    运维 or dba,进行 SQL 数据库服务器 参数调优。
面试:https://www.cnblogs.com/setalone/p/14851000.html
95. 你是如何监控你们的数据库的?你们的慢日志都是怎么查询的?
监控的工具有很多,例如zabbix,lepus,我这里用的是lepus

96. 你是否做过主从一致性校验,如果有,怎么做的,如果没有,你打算怎么做?
主从一致性校验有多种工具 例如checksum、mysqldiff、pt-table-checksum等

。不要说我觉得。

一.:Mysql 的架构介绍(1~9)

1:Mysql 简介:

   1)概述:
在这里插入图片描述
   2)高级 MySQL :(完整的 mysql 优化,需要很深的功底,大公司甚至有专门的 DBA 维护。)
    -1:Mysql 内核、Sql 优化工程师、Mysql 服务器优化、
    -2:各种参数常量设定、查询语句优化、
    -3:主从复制、软硬件升级、容灾备份、sql 编程 等。


2:Mysql 的 Linux 安装:(安装、修改配置文件)

5.7 及以上安装:

。。。老韩 5.5 安装:起。。。。。。。。。。。。。。。。。。。。
   1)下载:https://downloads.mysql.com/archives/community/
在这里插入图片描述
   2)检查 当前系统 是否安装过 mysql:
在这里插入图片描述

   3)安装 mysql 服务端:
    -1:安装包放在:/opt 目录下:(出现问题:yum remove mysql-libs)
    -2:安装:

rpm -ivh MySQL-server-5.5.48-1.linux2.6.x86_64.rpm
-- 提示
/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h bogon password 'new-password'

在这里插入图片描述

   4)安装 Mysql 客户端:
    -1:安装包放在:/opt 目录下:
    -2:安装:

rpm -ivh MySQL-client-5.5.48-1.linux2.6.x86_64.rpm

在这里插入图片描述

   5)查看 Mysql 安装时,创建的 Mysql 用户和 Mysql 组:(top 命令)
在这里插入图片描述

   6)Mysql 服务的(启动|停止):(start|stop)
在这里插入图片描述

   7)mysql 服务启动后,开始连接:
    -1:首次连接成功:(没有输入密码)
在这里插入图片描述
    -2:按照 安装 Server 中的提示,修改登录密码:

/usr/bin/mysqladmin -u root password 123456

在这里插入图片描述

   8)开机 自启动 Mysql 服务:
在这里插入图片描述

   9)修改 配置文件位置:
    -1:(Mysql 配置文件位置:/usr/share/mysql )(此文件与 调优有关)
    -2:(拷贝进 /etc 所有配置的集散地)
在这里插入图片描述

   10)设置外网可访问:
在这里插入图片描述
。。。。老韩 5.5 安装:结束。。。。。。。。。。。。。。。。。。。

   11)修改字符集 & 数据存储路径:
    -1:插入中文显示乱码:(建库、建表)
在这里插入图片描述
    -2:查看字符编码:(默认 客户端 和 服务端 都使用了 latin1 ,所以会中文乱码)

	-- 字符串的编码与解码
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str = URLEncoder.encode("😂", StandardCharsets.UTF_8.toString());
        System.out.println(str);

        String dStr = URLDecoder.decode("%F0%9F%98%82", StandardCharsets.UTF_8.toString());
        System.out.println(dStr);	// 😂
    }
show variables like 'character%';

show variables like '%char%';

在这里插入图片描述
    -3:修改编码:(在 mysql 配置文件中,修改)
在这里插入图片描述

 17 [client]
 18 password        = 123456
 19 port            = 3306	# mysql 端口
 20 socket          = /var/lib/mysql/mysql.sock
 -- mysql 客户端连接mysql服务器时,指定客户端的编码规则
 -- 客户端 会忽略操作系统当前使用的字符集,
 	直接将 default-character-set 启动选项中指定的值,作为客户端默认的字符集。
 21 default-character-set=utf8	
--影响参数:character_set_client,character_set_connection 和character_set_results。
--注意:修改后无需重启数据库。
 
 	-- 可以控制:(以下四个变量,都是 SESSION 级别的)
 		-- 描述:服务器认为,请求是按照,该系统变量指定的字符集,进行编码的。
 		-- show variables like 'character_set_client'; == utf8; 

		-- 描述:服务器再处理请求时,会把请求字节序列从 character_set_client 
				转换为 character_set_connection。
 		-- show variables like 'character_set_connection'; == utf8
 		-- show variables like 'collation_connection'; == gbk_chinese_ci

		-- 描述:服务器采用,该系统变量,指定的字符集,对返回给客户端的字符串,进行编码。
 		-- show variables like 'character_set_results'; == utf8

 26 [mysqld]
 27 port            = 3306	# mysql 端口
    skip-grant-tables	-- 跳过密码检查(忘记密码时使用)
 28 character_set_server=utf8	# 设置编码
 29 character-set-client=utf8	# 设置编码 --(貌似可以不用)
 30 collation-server=utf8_general_ci	# 设置编码
-- character_set_server=utf8
-- 影响参数:character_set_server 和 character_set_database
-- 注意:修改后要重启数据库才能生效。

 # (注意,Linux 下,mysql 安装完默认:表名区分大小写,列名不区分大小写;0:区分;1:不区分)
 # lower_case_table_names=1
 
 # 设置最大连接数,默认为:151,mysql 服务器允许最大连接数:16348.
 #  max_connections=1000


139 [mysql]
140 no-auto-rehash
141 default-character-set=utf8

    -4:重启 Mysql,还是乱码:需要重新创建数据库,重新创建表,插入中文呢数据,就不显示乱码了。

   12)Mysql 的 安装配置:
    -1:windows:D:\devSoft\MySQLServer5.5\data
    -2:Limux:默认路径:/var/lib/mysql。(查看:ps -ef | grep mysql)
在这里插入图片描述
在这里插入图片描述


3:Mysql 配置文件:(主要配置文件)

   1)二进制日志(log-bin)(主要用于主从复制)
(配置文件中:配置文件存放位置)
在这里插入图片描述
   2)错误日志(log-error)
    -1:位置:(配置文件:my.cnf 中配置路径:mysql/data/mysqlerr.err )
    -2:默认关闭:
    -3:记录严重的(警告 & 错误)信息,每次(启动 & 关闭)的详细信息等。

   3)查询日志(log)(可用于 慢查询分析)
    -1:默认关闭:
    -2:记录查询的 sql 语句,如果开启,会降低 mysql 整体性能。
    -3:因为,记录日志也是需要消耗系统资源的。

   4)数据文件:
    -1:两系统:
      a:Windows:D:\devSort\MysqlServer5.5\data 目录下,可以挑选很多库。
      b:Linux:默认路径:( /var/lib/mysql )

    -2:xx.frm 文件:(存放:表结构)(format)
    -3:xx.myd 文件:(存放:表数据)(my data)
    -4:xx.myi 文件:(存放:索引)(my index)

   5)如何配置:(配置文件位置)
    -1:windows:( my.ini 文件 )
    -2:Linux:( /etc/my.cnf 文件 )


4:Mysql 逻辑架构介绍:

   1)总体概览:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


5: Mysql 存储引擎:(详见 数据库 基础)

   1)查看命令:

-- 查看本 mysql ,现在已提供什么引擎:
show engines;

-- 查看当前默认存储引擎:
show variables like '%storage_engine%';

   2)(InnoDB|MyISAM|Memory):
在这里插入图片描述
    -1:InnoDB: 支持事务 ,支持主外键,支持行级锁(适合高并发)。(关注点为:事务)
    -2:MyISAM:不支持事务,不支持主外键,支持表级锁(不适合高并发)。(添加速度快)
    -3:Memory:数据存储在内存中【重启mysql服务,数据丢失,但是表结构还在】。执行速度快(没有 IO 读写),默认支持索引(hash 表)

   3)阿里、淘宝用哪个:(存储引擎给换了)
在这里插入图片描述




二.(1):索引优化分析:(10~19)

1:性能下降 SQL 慢:(执行时间长、等待时间长)

   1)查询语句写得烂:各种连接、各种子查询,导致用不上索引。或者没建索引。

   2)索引失效:(建了索引没用上)

mysql> select * from user where name = '张三';
+------+--------+
| id   | name   |
+------+--------+
|    1 | 张三   |
+------+--------+

-- 创建单值索引
mysql> create index idx_user_name on user (name);

-- 创建复合索引
mysql> create index idx_user_idName on user (id, name);

   3)关联查询 太多 join:(设计缺陷 / 不得已的需求)

   4)服务器调优 及 各个参数设置不合理:(缓冲、线程数等)


2:常见通用的 Join 查询:

   1)SQL 执行顺序:
    -1:手写:

SELECT DISTINCT *
FROM table01
         LEFT JOIN table2 ON
    ta = tb
WHERE a = 1
GROUP BY age
HAVING age = 1
ORDER BY age ASC
LIMIT 2,2;

    -2:机读:(通过 mysql 优化器认为最优的方式,去运行)
在这里插入图片描述
在这里插入图片描述

   2)Join 图:
在这里插入图片描述

   3)建表 SQL:

-- 部门名称、楼层
create table tb1_dept(
	id int(11) primary key auto_increment,
	dept_name varchar(40) default null,
	ioc_add varchar(40) default null
)character set utf8 collate utf8_general_ci engine innodb;

-- 员工姓名、部门id
create table tb1_emp(
	id int(11) primary key auto_increment,
	name varchar(20) default null,
	dept_id int(11) default null
	-- foreign key (dept_id) references tb1_dept(id)
)character set utf8 collate utf8_general_ci engine innodb;

insert into tb1_dept (dept_name,ioc_add) values ('dept_name_a','11');
insert into tb1_dept (dept_name,ioc_add) values ('dept_name_b','12');
insert into tb1_dept (dept_name,ioc_add) values ('dept_name_c','13');
insert into tb1_dept (dept_name,ioc_add) values ('dept_name_d','14');
insert into tb1_dept (dept_name,ioc_add) values ('dept_name_e','15');

INSERT INTO tb1_emp (name, dept_id) VALUES('z1', 1);
INSERT INTO tb1_emp (name, dept_id) VALUES('z2', 1);
INSERT INTO tb1_emp (name, dept_id) VALUES('z3', 1);
INSERT INTO tb1_emp (name, dept_id) VALUES('a4', 2);
INSERT INTO tb1_emp (name, dept_id) VALUES('x5', 2);
INSERT INTO tb1_emp (name, dept_id) VALUES('a6', 3);
INSERT INTO tb1_emp (name, dept_id) VALUES('a7', 51);

在这里插入图片描述

   4)7 种 join 测试:(查询以上 两张表)
在这里插入图片描述
(mysql 不支持 full outer join,可以使用 【 union|union all 】替换)
在这里插入图片描述


3:索引简介:

   1)是什么:
    -1:MySQL 官方,对索引的定义为:索引(Index),是帮助 MySQL,高效获取数据的数据结构。
    -2:索引的本质:索引是一种 数据结构。
    -3:索引的目的在于提高查询效率:可以类比字典。
    -4:可以简单理解为:排好序的快速查找数据结构。(影响:排序,查找)
      a:讲解:(二叉树)(BTREE 索引) (平衡二叉树)
在这里插入图片描述
在这里插入图片描述
      b:结论:(数据一般不删除,只是修改状态)
在这里插入图片描述

    -5:索引存储位置:
      a:一般来说:索引本身也很大,不可能全部存储在内存中。
      b:因此,索引往往以 索引文件 的形式,存储在磁盘上。
      c:存放位置:( /var/lib/mysql )

    -6:索引结构:(B+Tree :多路平衡查找树)
在这里插入图片描述
   1)Mysql 索引结构:
    -1:BTree:(不用)
在这里插入图片描述
    -2:为什么是 B+ 树:(在 B-树的基础上,把所有节点,放在叶子结点上,形成链表)


   2)优势:
    -1:通过索引的数据结构:提高数据检索的效率,降低数据库的 IO 成本。
    -2:通过 索引列:对数据进行排序,降低数据排序成本,降低了 CPU 的消耗。

   3)劣势:
    -1:实际上,索引也是一张表:
      a:该表保存了 主键 与 索引字段,并通过 指针方式,指向实体表的记录。
      b:所以,索引也是要占用空间的。

    -2:虽然:索引大大提高了查询速度,同时也会降低 表的更新速度:
      a:如:对表进行 insert、update、delete。
      b:因为:更新表时,Mysql 不仅要保存数据,还要维护索引文件;

    -3:索引,只是提高查询效率的一个因素:
      a:如果 Mysql 中有大数据量的表,就需要花时间研究,建立最优秀的索引,或优化查询。

   4)mysql 索引分类:
(一张表的索引,最好不要超过 5 个)
(一个查询,同时只能加载一个索引去使用)
    -1:单值索引:即:一个索引只包含单个列,一个表可以有多个单列索引。(复合索引优于单值索引)

    -2:唯一索引:即:索引列的值必须唯一,但允许有空值;(例如:主键约束|唯一约束)

    -3:复合索引:即:一个索引包含多个列;

    -4:基本语法:(加上 Unique 就是唯一索引)
在这里插入图片描述
在这里插入图片描述

   5)mysql 索引结构:
    -1:BTree 索引:(BTree 的 检索原理:下面)
在这里插入图片描述
在这里插入图片描述
    -2:Hash 索引:
    -3:full-text 全文索引:
    -4:R-Tree 索引:

   6)哪些情况,需要创建索引:
    -1:主键自动建立 唯一索引;
    -2:频繁作为(where)查询条件的字段,应该创建索引;;where 条件里用不到的字段,不要创建索引。

    -3:查询中 与 其他表关联的字段,外键关系建立索引;(外键字段创建索引)
    -4:频繁更新的字段不适合创建索引;(因为 每次更新,要修改数据的同时,还要维护索引)

    -5:(单键|组合)索引的选择问题?(在高并发下,倾向于组合索引)
    -6:查询中,排序字段 若通过索引去访问,将大大提高排序速度;
    -7:查询中,统计或者分组的字段;(分组前,必排序)

   7)哪些情况,不要创建索引:
    -1:表记录太少:
    -2:经常 增删改 的表:
在这里插入图片描述
    -3:数据重复 且 分布平均的表字段:(索引的选择性 越接近 1 ,效率越高)
在这里插入图片描述


二.(2):索引优化分析 — 性能分析:(20~30)

1:Mysql Query Optimiter:

(mysql 自带的:查询优化器模块)
在这里插入图片描述

2:Mysql 常见瓶颈:

在这里插入图片描述

3:Explain 介绍:

4:Explain 各字段解释:

5:Explain 热身 case:

   1)判断 SQL 执行循序:
在这里插入图片描述




二.(3):索引优化分析 — 索引优化(31~43)

1:索引分析:

   1)单表:
    -1:建表 SQL:

create table if not exists article
(
    id          int(10) unsigned not null primary key auto_increment,
    author_id   int(10) unsigned not null,
    category_id int(10) unsigned not null,
    views       int(10) unsigned not null,
    comments    int(10) unsigned not null,
    title       varbinary(255)   not null,
    content     text             not null
);

INSERT INTO article (author_id, category_id, views, comments, title, content)
VALUES (1, 1, 1, 1, '1', '1'),
       (2, 2, 2, 2, '2', '2'),
       (1, 1, 3, 3, '3', '3'),
       (4, 4, 4, 4, '4', '4');

在这里插入图片描述

    -2:案例
      a:查询:(结论:必须进行优化)

-- 查询 category_id = 1 且 comments > 1 的情况下的全部数据。
-- 并用 views 倒序排序。
explain
select a.id,
       a.author_id
from article a
where a.category_id = 1
  AND a.comments > 1
order by a.views DESC
limit 1;

+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | a     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+

-- 结论:很显然,type 为 ALL,即最坏的情况。
-- Extra 里 还出现了 Using filesort ,也是最坏的情况
-- 所以,必须进行优化

      b:开始优化:(创建复合索引)

-- 创建 索引:
create index idx_article_ccv on article (category_id, comments, views);

-- 再次查询,显示结果如下(用到了索引)(但范围以后的索引会失效)
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------------+
| id | select_type | table | type  | possible_keys   | key             | key_len | ref  | rows | Extra                       |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | a     | range | idx_article_ccv | idx_article_ccv | 8       | NULL |    1 | Using where; Using filesort |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

      c:范围以后的索引,会失效:( 条件尽量写 等于)
在这里插入图片描述
在这里插入图片描述

    -3:上面的索引:不太合适范围查询,因为出现了 文件排序;故 删除索引。

drop index idx_article_ccv on article;
-- 重新创建索引(跳过排序字段),再次查询
create index idx_article_cv on article (category_id, views);

在这里插入图片描述


   2)两表:
    -1:建表 SQL

create table if not exists class (
    id   int(10) primary key auto_increment,
    card int(10) unsigned not null
);
-- 随机插入数据
insert into class(card) values (floor(1 + (rand() * 20)));
insert into class(card) values (floor(1 + (rand() * 20)));

create table if not exists book (
    bookid int(10) primary key auto_increment,
    card   int(10) unsigned not null
);
-- 随机插入数据
insert into book(card) values (floor(1 + (rand() * 20)));
insert into book(card) values (floor(1 + (rand() * 20)));

在这里插入图片描述

    -2:案例:(索引应该 加在 左表 还是 右表)
      a:查询:(结论:type 为 ALL,必须进行优化)
在这里插入图片描述

      b:为 book 标,添加索引优化:(book 为 右表)(左连接,加右表)

create index idx_book_card on book (card);

在这里插入图片描述

      c:为 class 表,添加索引优化:(book 为 右表)
(观察到:左连接,索引加在左表上的话,type=index,rows=40,效果没有之前好)

drop index idx_book_card on book;
create index idx_class_card on class (card);

在这里插入图片描述
      d:结论:左连接索引加在右表,右连接索引加在左表。(表的位置交换一下也可以)


   3)三表:
    -1:建表 SQL:

create table if not exists phone (
    phoneid int(10) primary key auto_increment,
    card    int(10) unsigned not null
);

INSERT INTO phone (card) VALUES (floor(1 + (rand() * 20)));
INSERT INTO phone (card) VALUES (floor(1 + (rand() * 20)));

在这里插入图片描述

    -2:案例:
      a:查询:(结论:type 为 ALL,必须进行优化)
在这里插入图片描述

      b:为 book、phone 添加索引优化,再次查询。

create index idx_book_card on book (card);
create index idx_phone_card on phone (card);

在这里插入图片描述

      c:结论:
(左连接建右表,右连接建左表,依然适用)
(永远是:小表驱动大表)(小表的 type 可以为 all,但是大表,必须用索引)
在这里插入图片描述



2:索引失效(建表 SQL):

create table if not exists staffs(
    id       int primary key auto_increment,
    name     varchar(24) not null default '' comment '姓名',
    age      int         not null default 0 comment '年龄',
    pos      varchar(20) not null default '' comment '职位',
    add_time timestamp   not null default current_timestamp comment '入职时间'
) character set utf8 comment '员工记录表';

INSERT INTO staffs (name, age, pos, add_time) VALUES ('z3', 22, 'manager', CURRENT_TIMESTAMP);
INSERT INTO staffs (name, age, pos, add_time) VALUES ('Jujy', 23, 'dev', CURRENT_TIMESTAMP);
INSERT INTO staffs (name, age, pos, add_time) VALUES ('2000', 23, 'dev', CURRENT_TIMESTAMP);

select * from staffs;

create index idx_staffs_nameAgePos on staffs (name, age, pos);

在这里插入图片描述


3:索引失效(案例):

在这里插入图片描述
   1)全值匹配我最爱:(全值匹配我最爱)
(索引:name、age、pos)(下面的搜索,精度越来高)
在这里插入图片描述

   2)最佳左前缀 法则:(带头大哥不能死,中间兄弟不能断)
在这里插入图片描述

   3)不在 索引列上 做任何操作:(索引列上少计算)
(计算、函数、(自动 / 手动)类型转换),都会导致索引失效而转向全表扫描。
在这里插入图片描述

   4)存储引擎,不能使用索引中,范围条件右边的列:(范围之后全失效)
(范围列用到,后面的失效)
(in、like、between and)(like 使用 % 开头 ,也是范围)

在这里插入图片描述

   5)尽量使用 覆盖索引:
    -1:(只访问索引的查询(索引排序 与 查询列一致),减少 select * )
    -2:select * :(不仅不能使用覆盖索引,还可能占用内存空间大了之后,把 sort_buffer 占满,由单路排序 转变为 双路排序)(总结详解)

    -3:如何使用:
      a:使用 覆盖索引 和 不使用 覆盖索引
在这里插入图片描述
      b:只用一部分 覆盖索引:(这个不区分先后顺序)
在这里插入图片描述

   6)Mysql 在使用 不等于( != 或 <> )的时候:(无法使用索引会导致全表扫描)
在这里插入图片描述

   7)( is null、is not null )也无法使用索引:
(SQL 中尽量避免空值,写 default 值也可以)
在这里插入图片描述

   8)like 以通配符开头(‘%abc…’)Mysql 索引失效,会变成全表扫描的操作:(百分 like 加右边)
(like 使用 % 开头 ,也是范围)(但是 like 以常量值开头,就不是范围,后面的字段依然可以使用索引)
    -1:测试:使用 like ‘%abc’ ,索引会失效,转为全表扫描;
在这里插入图片描述

    -2:问题:解决 Like ‘%abc%’ 时,索引不被使用的方法 ?
( 使用覆盖索引查询字段:要不全部吻合,要不沾边就行,但不能超过

-- 建表 sql
create table tbl_user(
    id    int(11) primary key auto_increment,
    name  varchar(20) default null,
    age   int(11)     default null,
    email varchar(20) default null
) character set utf8  engine innodb;

INSERT INTO tbl_user (name, age, email) VALUES ('1aa1', 21, 'a@163.com');
INSERT INTO tbl_user (name, age, email) VALUES ('2aa2', 222, 'b@163.com');
INSERT INTO tbl_user (name, age, email) VALUES ('3aa3', 265, 'c@163.com');
INSERT INTO tbl_user (name, age, email) VALUES ('4aa4', 21, 'd@163.com');

-- 创建索引
create index idx_user_nameAge on tbl_user (name, age);

在这里插入图片描述
在这里插入图片描述
    -3:覆盖索引,索引失效情况:
在这里插入图片描述

   9)字符串类型,不加单引号索引失效: (varchar 不加单引号,索引失效)
更会:(导致行锁升级为表锁)
(数字不加引号,mysql也能查出来)
(但是:不加单引号,会自动进行类型转换,索引失效)

在这里插入图片描述
(如果是数字,加不加单引号都行。)
在这里插入图片描述

   10)少用 or,用它连接时,会导致索引失效:
在这里插入图片描述

  3.x:索引使用:小总结:(口诀)

全值匹配我最爱,最佳左前缀法则;
带头大哥不能死,中间兄弟不能断;
索引列上无计算,范围之后全失效;
like百分加右边,覆盖索引不写*。
字符串里加引号,不等空值和or。

   12)习题案例:
在这里插入图片描述



4:面试题讲解:

先说结论:
1、索引分析:定值为常量、范围之后失效,最终看排序,一般 order by 是给个范围:
2、group by 基本上都需要进行排序(分组之前必排序),会有临时表产生:

   1)建表、建索引 语句:

create table test03(
    id int primary key not null auto_increment,
    c1 char(10),
    c2 char(10),
    c3 char(10),
    c4 char(10),
    c5 char(10)
);

INSERT INTO test03 (c1, c2, c3, c4, c5) VALUES ('a1', 'a2', 'a3', 'a4', 'a5');
INSERT INTO test03 (c1, c2, c3, c4, c5) VALUES ('b1', 'b2', 'b3', 'b4', 'b5');
INSERT INTO test03 (c1, c2, c3, c4, c5) VALUES ('c1', 'c2', 'c3', 'c4', 'c5');
INSERT INTO test03 (c1, c2, c3, c4, c5) VALUES ('d1', 'd2', 'd3', 'd4', 'd5');
INSERT INTO test03 (c1, c2, c3, c4, c5) VALUES ('e1', 'e2', 'e3', 'e4', 'e5');

create index idx_test03_c1c2c3c4 on test03 (c1, c2, c3, c4);

在这里插入图片描述

   2)简单测试 索引:
在这里插入图片描述

   3)复杂分析:
    -1:复杂分析(1):
      a:(1234 或 4321 或 1324,都能使用索引,全出现了就行,查询优化器会开启自我优化分析)
      b:(在 常量的范围,会优化分析)(前提是,建立的索引不需全部都在,少一个就不会自动优化)
      c:(但最好,怎么建立索引,怎么使用索引)
在这里插入图片描述

    -2:复杂分析(2)(范围之后全失效,但范围会用得到;用到了 3 个)
在这里插入图片描述

    -3:复杂分析(3)(优化器会自动优化顺序,用到了 4 个)
在这里插入图片描述

    -4:复杂分析(4)(c1,c2 用到了查找,c3 用到了排序。但是:c4 没有用到索引)
在这里插入图片描述

    -5:复杂分析(5)排序
在这里插入图片描述

    -6:复杂分析(6)
在这里插入图片描述

    -7:复杂分析(7)
在这里插入图片描述


5:一般性建议::

(只要是 range ,索引一定是走散了)
在这里插入图片描述





三.:查询截取分析(44~50)

1:查询优化:

   1)永远小表驱动大表:
( 类似 嵌套循环 Nested Loop )(减少数据库 连接与释放):
    -1:原理:(选择 左面的)
在这里插入图片描述
    -2:case:(小表驱动大表 与 in 和 exists 的使用)
(怎么换:id in 抹掉,换掉 exists ,后面变为子查询)
在这里插入图片描述
    -3:exists 原理:(in 写法的变种)(怎么换、原理:true保留,false算了)
a:在 子查询中,需要引用到主查询的字段数据,使用 exists 关键字。
b:exists 后面的字查询,最少返回一条数据,则整个条件返回 true。
c:用在 where 之后,子查询之前。
d:关注是否可以查询到数据,而不在乎查询到的值。
e:exists 关键字后面跟着一个子查询,当该子查询可以查出 至少一条记录时,则 返回true,exists 条件成立。
在这里插入图片描述

    -4:in 变 exists 案例:(结果一样)
在这里插入图片描述


   2)order by 关键字优化:
    -1:order by 子句,尽量使用 Index 方式排序,避免使用 FileSort 方式排序。
      a:建表、创建索引:

create table tblA(
    age   int,
    birth timestamp not null
);

INSERT INTO tblA (age, birth) VALUES (22, now());
INSERT INTO tblA (age, birth) VALUES (23, now());
INSERT INTO tblA (age, birth) VALUES (24, now());

create index idx_tblA_ageBirth on tblA (age, birth);

select * from tblA;
+------+---------------------+
| age  | birth               |
+------+---------------------+
|   22 | 2022-04-11 21:10:16 |
|   23 | 2022-04-11 21:10:16 |
|   24 | 2022-04-11 21:10:16 |
+------+---------------------+

      b:case:(只要从 age 开始,就可以使用到索引)
在这里插入图片描述
在这里插入图片描述
      c:Mysql 支持两种方式的排序:(FileSort & Index)
1、 (index 效率高,它指 MySQL 扫描索引本身完成排序)
2、(FileSort 效率低)

      d:Order by 满足两种情况,会使用 Index 方式排序:
1、(Order by 语句使用索引最左前列)
2、(使用 Where 子句 与 Order by 子句条件列,组合满足索引最左前列)

    -2:尽可能 在索引列上,完成排序操作;遵照索引建的最佳做前缀:

    -3:如果不在索引列上排序,FileSort 有两种算法:(双路排序 & 单路排序)
      a:mysql 双路排序:(两次IO,IO很耗时,Mysql 4.1 之前使用)
      b:mysql 单路排序:
在这里插入图片描述
      c:结论 及 引申出的问题:
(由于单路算法是后出的,总体好过双路排序)
(但是单路有问题,可能比双路排序更耗时)
在这里插入图片描述

    -4:优化策略:
在这里插入图片描述
    -5:小总结:
在这里插入图片描述


   3)group by 关键字优化:(和 order by 类似)
在这里插入图片描述



2:慢查询日志:

   1)是什么:
在这里插入图片描述
   2)怎么玩:
    -1:说明:(MySQL 中,大部分牛逼的功能,都是默认关闭)
在这里插入图片描述
    -2:(查看是否开启 & 如何开启)

-- 查看
mysql> show variables like '%slow_query_log%';
+---------------------+-------------------------------+
| Variable_name       | Value                         |
+---------------------+-------------------------------+
| slow_query_log      | OFF                           |
| slow_query_log_file | /var/lib/mysql/bogon-slow.log |
+---------------------+-------------------------------+

-- 开启(只对当前数据库生效,重启 mysql server后,会失效)
mysql> set global slow_query_log = 1;
Query OK, 0 rows affected (0.00 sec)

在这里插入图片描述

    -3:开启了 慢查询日志后,什么样的 SQL,才会被记录到:慢查询日志里面呢?

    -4:Case:(设置阈值时间、并查看日志)
      a:设置 阙值时间:
在这里插入图片描述

-- 查看默认时间
mysql> show variables like 'long_query_time%';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+

-- 修改默认时间
mysql> set global long_query_time = 3;
Query OK, 0 rows affected (0.00 sec)

在这里插入图片描述
      b:记录慢 SQL,并后续分析:
在这里插入图片描述
      c:查询当前系统中,有多少条慢查询记录:(超过阈值的 sql)

mysql> show global status like '%Slow_queries%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries  | 2     |
+---------------+-------+

    -5:配置版:(永久生效:不常用)
在这里插入图片描述


   3)日志分析工具:(mysqldumpslow)
    -1:是什么:生产环境中,MySQL 提供的日志分析工具。
    -2:怎么用:( mysqldumpslow --help )
在这里插入图片描述
    -3:工作常用参考:(灵活组合得到信息)
在这里插入图片描述


3:批量数据脚本:(插入 1000w 数据)

   1)建表:

create table dept (
    id     int unsigned primary key auto_increment,
    deptno mediumint unsigned not null default 0,
    dname  varchar(20)        not null default '',
    loc    varchar(13)        not null default ''
);

create table emp (
    id       int unsigned primary key auto_increment,
    empno    mediumint unsigned not null default 0 comment '编号',
    ename    varchar(20)        not null default '' comment '名字',
    job      varchar(9)         not null default '' comment '工作',
    mgr      mediumint unsigned not null default 0 comment '上级编号',
    hiredate date               not null comment '入职时间',
    sal      decimal(7, 2)      not null comment '薪水',
    comm     decimal(7, 2)      not null comment '红利',
    deptno   mediumint unsigned not null default 0 comment '部门编号'
);

   2)设置参数,防止大数据插入报错( log_bin_trust_function_creators ):

-- 查看
mysql> show global variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF   |
+---------------------------------+-------+

-- 开启
mysql> set global log_bin_trust_function_creators = 1;
Query OK, 0 rows affected (0.00 sec)

在这里插入图片描述
   3)创建函数,保证每条数据 都不同:
    -1:随机产生字符串:

delimiter $$ -- sql 结束符号变为 $$;
create function rand_string(n int) returns varchar(255)
begin
	declare chars_str varchar(100) default 'abcdefghijklmnopqrstuvwxyz';
	declare return_str varchar(255) default '';
	declare i int default 0;
	while i < n do
		set return_str = CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));
		set i = i+1;
	end while;
	return return_str;
end $$

    -2:随机产生部门编号:

delimiter $$
create function rand_num()
returns int(5)
begin
	declare i int default 0;
	set i = floor(100+RAND()*10);
	return i;
end $$

    -3:假如要删除:(drop function rand_num)

   4)创建存储过程:
    -1:创建 往 emp 表中,插入数据的存储过程:

delimiter $$
create procedure insert_emp(in start int(10),in max_num int(10))
begin
	declare i int default 0;
	# set autocommit = 0 把 autocommit 设置成 0,关掉自动提交。
	set autocommit = 0;
	repeat set i = i+1;
	INSERT into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) values
	((start=i),rand_string(6),'salesman',0001,curdate(),2000,400,rand_num());
	until i = max_num
	end repeat;
	commit;
end $$

    -2:创建 往 dept 表中,插入数据的存储过程:

delimiter $$
create procedure insert_dept(in start int(10),in max_num int(10))
begin
	declare i int default 0;
	set autocommit = 0;
	repeat
	set i = i+1;
	INSERT INTO dept (deptno, dname, loc) VALUES((start+i), rand_string(10), rand_string(8));
	until i = max_num
	end repeat;
	commit;
end $$

    -3:假如要删除:(delimiter)(drop procedure insert_emp)
    -4:SQL 结束标记 改回来:(delimiter ;)

   5)调用存储过程:
    -1:插入 dept 表:

-- 插入 10 条:
call insert_dept(100,10);

-- 插入 50 万条:
call insert_dept(100001,500000);

    -2:插入 emp 表:

-- 插入 50 万条:
call insert_emp(100001,500000);



4:Show Profile:

   1)是什么:
    -1:是 mysql 提供的,可以用来分析:当前会话中语句执行的资源消耗情况。
    -2:可以用于 SQL 的 调优的测量。

   2)官网:https://dev.mysql.com/doc/refman/8.0/en/show-profile.html

   3)默认参数下,参数处于关闭状态,并保存最近 15 次的运行结果:

   4)分析步骤:
    -1:查看当前 mysql 版本是否支持:

mysql> show variables like 'profiling%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| profiling              | ON    |
| profiling_history_size | 15    |
+------------------------+-------+

    -2:开启功能:

set profiling = on;

    -3:运行 SQL:

mysql> select * from dept limit 0,5

mysql> select * from emp group by id%10 limit 150000;
10 rows in set (1.96 sec)

mysql> select * from emp group by id%10 order by deptno;
10 rows in set (1.07 sec)

    -4:查看结果:( show profiles )

mysql> show profiles;
+----------+------------+--------------------------------------------------------------------------------+
| Query_ID | Duration   | Query                                                                          |
+----------+------------+--------------------------------------------------------------------------------+
|        7 | 0.00140675 | select * from dept limit 0,5                                                   |
|        8 | 0.00120050 | explain select * from dept left join emp on dept.deptno = emp.deptno limit 0,5 |
|        9 | 0.96275650 | select * from emp group by id%10 limit 150000                                  |
|       10 | 1.08553950 | select * from emp group by id%100 limit 150000                                 |
|       11 | 1.06771725 | select * from emp group by id%10 order by deptno                               |
+----------+------------+--------------------------------------------------------------------------------+
11 rows in set (0.00 sec)

    -5:诊断 SQL:(查看 SQL 细节)(分解步骤)

mysql> show profile cpu, block io for query 9;
+--------------------------------+----------+----------+------------+--------------+---------------+
| Status                         | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+--------------------------------+----------+----------+------------+--------------+---------------+
| starting                       | 0.000034 | 0.000025 |   0.000000 |            0 |             0 |
| Waiting for query cache lock   | 0.000007 | 0.000006 |   0.000000 |            0 |             0 |
| checking query cache for query | 0.000093 | 0.000094 |   0.000000 |            0 |             0 |
| checking permissions           | 0.000013 | 0.000012 |   0.000000 |            0 |             0 |
| Opening tables                 | 0.000025 | 0.000025 |   0.000000 |            0 |             0 |
| System lock                    | 0.000018 | 0.000018 |   0.000000 |            0 |             0 |
| Waiting for query cache lock   | 0.000033 | 0.000033 |   0.000000 |            0 |             0 |
| init                           | 0.000192 | 0.000198 |   0.000000 |            0 |             0 |
| optimizing                     | 0.000019 | 0.000012 |   0.000000 |            0 |             0 |
| statistics                     | 0.000098 | 0.000101 |   0.000000 |            0 |             0 |
| preparing                      | 0.000034 | 0.000031 |   0.000000 |            0 |             0 |
| Creating tmp table             | 0.000234 | 0.000239 |   0.000000 |            0 |             0 |
| executing                      | 0.000016 | 0.000010 |   0.000000 |            0 |             0 |
| Copying to tmp table           | 0.961687 | 0.819602 |   0.000000 |            0 |             0 |
| Sorting result                 | 0.000087 | 0.000083 |   0.000000 |            0 |             0 |
| Sending data                   | 0.000057 | 0.000054 |   0.000000 |            0 |             0 |
| end                            | 0.000006 | 0.000005 |   0.000000 |            0 |             0 |
| removing tmp table             | 0.000011 | 0.000011 |   0.000000 |            0 |             0 |
| end                            | 0.000006 | 0.000006 |   0.000000 |            0 |             0 |
| query end                      | 0.000017 | 0.000017 |   0.000000 |            0 |             0 |
| closing tables                 | 0.000010 | 0.000009 |   0.000000 |            0 |             0 |
| freeing items                  | 0.000015 | 0.000015 |   0.000000 |            0 |             0 |
| Waiting for query cache lock   | 0.000004 | 0.000003 |   0.000000 |            0 |             0 |
| freeing items                  | 0.000025 | 0.000025 |   0.000000 |            0 |             0 |
| Waiting for query cache lock   | 0.000003 | 0.000003 |   0.000000 |            0 |             0 |
| freeing items                  | 0.000003 | 0.000003 |   0.000000 |            0 |             0 |
| storing result in query cache  | 0.000006 | 0.000005 |   0.000000 |            0 |             0 |
| logging slow query             | 0.000004 | 0.000004 |   0.000000 |            0 |             0 |
| cleaning up                    | 0.000005 | 0.000004 |   0.000000 |            0 |             0 |
+--------------------------------+----------+----------+------------+--------------+---------------+
29 rows in set (0.00 sec)

在这里插入图片描述
    -5:日常开发需要注意的结论:(以下四个,都是惹事的;有任何一个,必须优化)
在这里插入图片描述



5:全局查询日志:

(一张表,收集所有的 SQL)
(永远不要在,生产环境开启这个配置,只能在 测试环境使用)
(这个不常用,建议使用 show profile)
   1)配置启用:
在这里插入图片描述
   2)编码启用:
在这里插入图片描述




四.:Mysql 锁机制(51~60)

1:概述:

   1)定义:
在这里插入图片描述
   2)生活购物:
在这里插入图片描述
   3)锁的分类:
    -1:从对数据 操作的类型 分类:
a:读锁(共享锁):针对同一份数据,多个 读操作可以同时进行,而不会互相影响。
b:写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。

    -2:从对数据 操作的粒度 分类:
a:表锁:
b:行锁:

    -3:根据:(开销、加锁速度、死锁、粒度、并发性能),具体应用来选择不同的锁。


2:三锁 — 表锁:(偏读)(重要)

   1)特点:
    -1:偏向 MyISAM 存储引擎。
    -2:开销小、加锁块;无死锁。
    -3:锁定粒度大,发生锁冲突的概率最高,并发度最低。

   2)案例分析:
    -1:建表 SQL:(engine myisam)

create table mylock (
    id   int not null primary key auto_increment,
    name varchar(20)
) engine myisam;

INSERT INTO mylock (name) VALUES ('a');
INSERT INTO mylock (name) VALUES ('b');
INSERT INTO mylock (name) VALUES ('c');
INSERT INTO mylock (name) VALUES ('d');
INSERT INTO mylock (name) VALUES ('e');
INSERT INTO mylock (name) VALUES ('f');
-- 锁表
mysql> lock table mylock read, emp write;

-- 查看
mysql> show open tables;
+-----------+---------+--------+-------------+
| Database  | Table   | In_use | Name_locked |
+-----------+---------+--------+-------------+
| db02      | mylock  |      1 |           0 |
| db02      | emp     |      1 |           0 |
+-----------+---------+--------+-------------+

-- 解锁表(解开全部表的锁)
mysql> unlock tables;

    -2:加 读锁:(共享锁)(手动增加表的读锁)(看执行顺序读图)
a:自己会话:(可以读,不能改)
b:其他会话:(可以读、不能改)(改的时候进入阻塞状态)(表锁结束后,自动继续执行)
在这里插入图片描述
在这里插入图片描述

    -3:加 写锁:(独占锁)(排它锁):(手动增加 表写锁)
a:(自己能读能写,不能读写其他)
b:(别的会话无论读写,都进入阻塞状态)
在这里插入图片描述
在这里插入图片描述


   3)案例结论:
在这里插入图片描述
   4)表锁分析:

mysql> show status like 'table%';
+-----------------------+---------+
| Variable_name         | Value   |
+-----------------------+---------+
| Table_locks_immediate | 1000221 |
| Table_locks_waited    | 0       |
+-----------------------+---------+
2 rows in set (0.00 sec)

在这里插入图片描述


3:三锁 — 行锁:(偏写)(重要):

   1)特点:
    -1:行锁:偏向 InnoDB 存储引擎;
    -2:开销大,加锁慢;会出现死锁;
    -3:锁定粒度最小,发生锁冲突的概率最低,并发度也最好;
    -4:InnoDB 与 MyISAM 最大不同:(2)
      a:InnoDB:支持事务:(Transaction)
      b:InnoDB:采用了行级锁:

   2)由于行锁支持事物:(复习老知识)
    -1:事务(Transaction)及 ACID 属性:(原子性、一致性、隔离性、持久性)
    -2:并发事务处理,带来的问题:
      a:更新丢失:
      b:脏读:
      c:不可重复读:
      d:幻读:

    -3:事务隔离级别:(默认级别:可重复度)(有幻读,但是可以优化)
在这里插入图片描述


   3)案例分析:
    -1:建表 SQL:

create table test_innodb_lock (
    a int(11),
    b varchar(16)
) engine innodb;

insert into test_innodb_lock values (1, 'b2');
insert into test_innodb_lock values (3, '3');
insert into test_innodb_lock values (4, '400');
insert into test_innodb_lock values (5, '500');
insert into test_innodb_lock values (6, '600');
insert into test_innodb_lock values (7, '700');
insert into test_innodb_lock values (8, '800');
insert into test_innodb_lock values (9, '900');
insert into test_innodb_lock values (1, 'b1');
create index test_innodb_a_ind on test_innodb_lock (a);
create index test_innodb_lock_b_ind on test_innodb_lock (b);

在这里插入图片描述

    -2:行锁定,基本演示:
      a:关闭自动提交:( set autocommit = 0; )
1、(只影响修改后的行,只影响锁定的行,其他行查询修改不受影响)
2、(A更新不提交,B读之前的数据不会变化)
3、(A更新不提交,B修改阻塞,A commit之后才可以修改)
4、(会话B如果自动 commit,B 就不用再次 commit ,就可以读到 A 行锁提交后的数据)
在这里插入图片描述

    -3:无索引行锁,升级为表锁(varchar 字段不使用 ’ ',行锁变为表锁 )
在这里插入图片描述
在这里插入图片描述

    -4:间隙锁危害(宁可错杀,不可放过)
修改范围内数据:(会锁住范围内的数据 --> 然后插入范围内数据时,会阻塞)
在这里插入图片描述
在这里插入图片描述

    -5:面试题:(如何锁定一行数据)(前面是锁一张表,现在是 锁定一行数据)
(修复数据时使用)

select * from test_innodb_lock where a = 8 for update;

在这里插入图片描述

   4)案例结论:
在这里插入图片描述

   5)行锁分析:
在这里插入图片描述

   6)优化建议:
在这里插入图片描述


4:三锁 — 页锁:(略)

在这里插入图片描述




五.:主从复制(61~61)

1:复制的基本原理:

(主从复制延迟解决:https://blog.csdn.net/soar_away/article/details/72615012)
   1)MySQL 主从复制原理:slave 会从 master 读取 binlog(二进制数据文件)来进行数据同步。

   2)特点:(从接入点开始复制,和 redis 不同)(有延时性)

   3)三步骤 + 原理图:
在这里插入图片描述


2:复制的基本原则:

   1)每个 slave 只有一个 master;
   2)每个 master 可以有多个 salve;(一主多从)
   3)每个 slave 只能有一个 唯一的服务器 ID;(为了区分)

3:复制的最大问题:(网络会有延迟)


4:一主一从常见配置:

   1)主机从机,保证 mysql 版本一致,且后台以服务运行:(主机从机同一网段,互相可以ping通)

   2)主从都配置在: ( my.cnf ) 配置文件中( mysqld )节点下:(都是小写)

   3)主机修改 my.cnf 配置文件:( vim /etc/my.cnf )
    -1:配置选项
(1) 28 server-id=1
(2) 57 log-bin=mysql-bin
(3) 58 log-err=mysql-err
在这里插入图片描述
    -2:配置案例:
在这里插入图片描述
在这里插入图片描述
    -3:binlog 日志三种格式:
在这里插入图片描述

   4)从机修改 my.cnf 配置文件:

-- 从服务器唯一 ID
  63  # server-id     = 1
 100  server-id       = 2
 
-- 启用 二进制日志
 117  log-bin=mysql-bin

-- 启用中继日志(不修改也可以)
      relay-log=mysql-relay

   5)主从重启 Mysql 服务器,并关闭防火墙:

   6)在 主机上建立账户,并授权给 slave:
(创建主从复制权限,所有表 slave 用户,指定密码 123123)
    -1:主机执行:

-- 主机 mysql 里执行,授权命令。
mysql> GRANT REPLICATION SLAVE ON *.* TO 'zhangxudong'@'从机数据库ip' IDENTIFIED BY '123456';

-- 刷新
mysql> flush privileges;

    -2:查询 master 状态:(show master status;)
file:binlog日志的名字。
position:切入点:(这上面文件的 341 位置,开始进行复制)。
Binlog_Do_DB:需要复制的数据库。
Binlog_Ignore_DB:忽略的数据库(不复制)。
(记录下:File & Position 的值)
在这里插入图片描述

   7)从机配置:(show slave status;)
    -1:连接主机:

change master to
    master_host = '192.168.43.69',	-- 主机 ip 地址
    master_user ='zhangsan',
    master_password ='123456',
    master_log_file ='mysql-bin.000004',	-- 日志文件(主机查看)
    master_log_pos =595413537;	-- 开始位置(主机查看)

(如果之前连过主机,重新配置主重:先stop slave,后 reset master ;然后在运行连接)
在这里插入图片描述
    -2:启动 从服务器 复制功能:( start slave )

    -3:检查是否成功:
在这里插入图片描述

   8)测试:主机(新建数据库|新建表|insert 记录),看到从机复制成功。

   9)如何停止 从服务器 复制功能:(从机执行:stop slave;)(注意:重启复制,要从新查看值 )

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中的内容是一个使用Jedis连接Redis的示例代码。在这个示例中,首先创建一个Jedis对象,并指定Redis服务器的IP地址和端口号。然后通过调用jedis.ping()方法来测试与Redis服务器的连通性。最后使用jedis.set()方法将一个键值对存储到Redis中,***这些数据不需要固定的模式,并且可以进行横向扩展。这意味着Redis可以处理这些非结构化的数据,并且能够支持高并发的访问。 引用指出大多数企业使用Linux版的Redis,而Windows版只适用于学习。在使用Redis之前,需要在命令行窗口中启动Redis服务端。然后可以使用redis-cli.exe命令连接到Redis服务器,并进行一系列的操作,如设置键值对、获取键值对等。 关于"尚硅谷周阳redis"这个提到的名字或词组,我在提供的引用内容中没有找到具体的相关信息。请提供更多的上下文或细节,我将尽力提供有关此主题的答案。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Redis—尚硅谷周阳](https://blog.csdn.net/qq_43056248/article/details/118355838)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Redis学习笔记(转尚硅谷周阳)](https://blog.csdn.net/m0_58779356/article/details/119740018)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值