首页 > 数据库 >Mysql 知识总结

Mysql 知识总结

时间:2023-03-07 22:24:54浏览次数:55  
标签:总结 事务 知识 id 索引 Mysql 数据 主键 select

1 mysql 数据类型

1. 整数类型

 tinyint: 1个字节(2^8)
 smallint: 2个字节
 mediumint:3个字节
 int:4个字节
 bigint:8个字节

2. 浮点数类型

float:(4个字节)1个符号位,8个指数位,23个尾数位,-3.4E+38 ~ 3.4E+38
double:(8个字节)1个符号位,11个指数位,52个尾数位,-1.79E+308 ~ 1.79E+308

3. 定点数类型

decimal(m,d)  (m-d) 整数部分位数,d 小数部分位数,如 decimal(5,2) 可以表示 -999.99 ~ 999.99

4. 日期/时间类型

year, time, date, datetime, timestamp

datetime 和 timestamp 区别

1,存储字节和支持范围不同
2,datetime 存储日期数据时,按照实际的格式存储,与时区无关。而 timestamp 存储以 UTC 格式保存。

5. 字符串类型

 char(M): 固定长度非二进制字符串,M 最大 255,这里范围表示字符数,而不是字节数。根据编码不同,每个字符占用字节不同。
 varchar(M): 变长非二进制字符串(长度小于 M,实际占用长度取决于内容),M 最大 255,这里范围表示字符数,而不是字节数。根据编码不同,每个字符占用字节不同。
 tinyText: 非常小的非二进制字符串,2*8 字节
 text:小的非二进制字符串,2*16 字节
 mediumtext:中等的非二进制字符串,2*24 字节
 longText:大的非二进制字符串,2*32 字节
 enum: `enum_str` enum('2','1') DEFAULT NULL
 set:  `set_str` set('1','2','3','4') DEFAULT NULL

enum 和 set 区别?

enum 只能选择一个,set 可以选择多个

char,varchar,text 区别?

1,char,varchar 可以有默认值,text 无法设置默认值。
2,char 表示定长,如果插入长度小于定义的长度,用空格填充。
varchar 表示变长,按照实际长度存储。
char 因为长度固定,存取速度比 varchar 快的多,方便程序的存储和查找。但是 varchar 更省空间。
3,char 最多 255 个字符,与编码无关。
varchar 最多 65535 个字节,utf8编码下 21843 个字符。

char(10) 和 int(10) 的区别?

varchar(10) 表示最大长度 10 个字符,超过报错。
int(10)表示宽度,宽度不够左边填充 0,超过就正常表示。

  1. 二进制类型
bit(M): 位字段类型,M 最大 64位。
binary(M):固定长度二进制字符串,M 表示可存储字符数,M 最大值 255,类似于 char
varbinary:可变长度的二进制字符串,M 表示可存储字符数,最大值 255,类似于 varchar
tinyblob:非常小的二进制字符串,2*8字节
blob:小的二进制字符串,2*16字节
mediumblob:中等的二进制字符串,2*24字节
longblob:大的二进制字符串,2*32字节

2,索引

  索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

索引的有点和缺点

索引优点:查询效率提高
索引缺点:需要单独维护索引,消耗时间空间。

2.1,几种常用索引

1)普通索引:normal
2)唯一索引:unique,可以 null 不能重复
3)主键索引:primary,不能 null 不能重复,每个表只有一个主键索引
4)组合索引
5)全文索引:fulltext,只有 myIsam 引擎支持。

2.2,聚簇索引和非聚簇索引

聚簇索引

  不是一种单独的索引类型,而是一种数据存储方式。InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分;
  一般建表会用一个自增主键做聚簇索引,没有的话MySQL会默认创建,但是这个主键如果更改代价较高,故建表时要考虑自增ID不能频繁update这点。
  我们日常工作中,根据实际情况自行添加的索引都是辅助索引,辅助索引就是一个为了需找主键索引的二级索引,现在找到主键索引再通过主键索引找数据;
  Innobd中的主键索引是一种聚簇索引,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引。

优点:
  1.数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快
  2.聚簇索引对于主键的排序查找和范围查找速度非常快

缺点:
  1.插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键
  2.更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。

非聚簇索引(辅助索引,二级索引)

  在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找。辅助索引叶子节点存储的不再是行的物理位置,而是主键值。通过辅助索引首先找到的是主键值,再通过主键值找到数据行的数据页,再通过数据页中的Page Directory找到数据行。
  Innodb辅助索引的叶子节点并不包含行记录的全部数据,叶子节点除了包含键值外,还包含了相应行数据的聚簇索引键。
  辅助索引的存在不影响数据在聚簇索引中的组织,所以一张表可以有多个辅助索引。在innodb中有时也称辅助索引为二级索引。

2.3,覆盖索引

  索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫 做覆盖索引。

2.4,执行计划 explain 解析

1. id

  id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的顺序增长的。
  id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。

2. select_type

  1)simple: 简单查询,不包含子查询和 union
  2)primary:复杂查询种最外城的查询。
  3)subquery:包含再 select 种的子查询。
  4)derived:包含再 from 子句中的子查询,mysql 将结果存放在一个临时表中,也称派生表。
  5)union:再 union 中第二个和随后的 select。

注:set session optimizer_switch='derived_merge=off'; #关闭mysql5.7新特性对衍生表的合并优化

3. table

  表示 explain 的一行正在访问哪个表。
  当 from 子句中有子查询时,table列是 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查询。
  当有 union 时,UNION RESULT 的 table 列的值为<union1,2>,1和2表示参与 union 的 select 行id。

4. type

  1)system:mysql能对查询的某部分进行优化并将其转化成一个常量,const 的特例子
  2)const:mysql能对查询的某部分进行优化并将其转化成一个常量
  3)eq_ref:主键或唯一索引被连接使用,最多只能返回一条数据。简单的 select 查询不会出现这种 type。 主键或者唯一索引被join连接使用。
  4)ref: 相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。
  5)range: 范围扫描通常出现在 in(), between ,> ,<, >= 等操作中。使用一个索引来检索给定范围的行。
  6)index: 扫描全索引就能拿到结果,一般是扫描某个二级索引,这种扫描不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点遍历和扫描,速度还是比较慢的,这种查询一般为使用覆盖索引,二级索引一般比较小,所以这种通常比ALL快一些。
  7)ALL:即全表扫描,扫描你的聚簇索引的所有叶子节点。通常情况下这需要增加索引来进行优化了。

依次从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL
一般来说,得保证查询达到range级别,最好达到ref

5. possible_keys
  显示查询可能使用哪些索引来查找

6. key
  实际才用哪个索引来优化对该表的访问。

7. key_len
  显示了在索引里使用的字节数。

8. ref
  这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名(例:film.id)

9. rows
  这一列是mysql估计要读取并检测的行数,注意这个不是结果集里的行数。

10. extra
   额外信息

11. filtered
  这里的filtered表示通过查询条件获取的最终记录行数占通过type字段指明的搜索方式搜索出来的记录行数的百分比。

12. partitions
  分区

2.5,索引的数据结构

  索引有分为 B+Tree 和 Hash 索引。

1. B 树

是一种自平衡树数据结构,它维护有序数据并允许以对数时间进行搜索,顺序访问,插入和删除。

1)每个节点最多有 m 个子节点
2)每个非叶子节点(除了根)具有至少 【m/2】 个子节点。
3)如果根不是叶节点,则根只是有两个子节点
4)具有 k-1 个子节点的非叶子系欸但包含 k-1 个键。
5)所有叶子都出现在同一水平,没有任何信息(高度一致)

2. B+树

B+Tree是BTree的一个变种,最大的区别是B+Tree内部节点不保存数据,只保存索引信息,所有数据都保存在叶子节点。

1)每个元素不保存数据,只保存索引,所有数据都保存在叶子节点
2)所有的叶子节点中包好了全部元素信息,以及指向这些元素记录的指针,且叶子节点本身依关键字的大小自小而大顺序连接。
3)所有的中间节点元素都同时存在于子节点,在子节点元素中是最大或最小元素。

3. hash

数组+链表

B+ 树和 hash 索引的区别?

1)Hash 索引不能进行范围查询,而 B+ 树可以。这是因为 Hash 索引指向的数据是无序的,而 B+ 树的叶子节点是个有序的链表。
2)Hash 索引不支持联合索引的最左侧原则(即联合索引的部分索引无法使用),而 B+ 树可以。对于联合索引来说,Hash 索引在计算 Hash 值的时候是将索引键合并后再一起计算 Hash 值,所以不会针对每个索引单独计算 Hash 值。因此如果用到联合索引的一个或者几个索引时,联合索引无法被利用。
3)Hash 索引不支持 ORDER BY 排序,因为 Hash 索引指向的数据是无序的,因此无法起到排序优化的作用,而 B+ 树索引数据是有序的,可以起到对该字段 ORDER BY 排序优化的作用。
4)Hash 索引适用于经常需要进行等值查询的时候。

2.6,索引最左配原则

  最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。

索引的底层是一颗B+树,那么联合索引当然还是一颗B+树,只不过联合索引的健值数量不是一个,而是多个。

  在创建联合索引时,首先会对最左边字段排序,也就是第一个字段,然后在保证第一个字段有序的情况下,在排序第二个字段,以此类推。所以联合索引最左列绝对有序,其他只有在前一个字段的基础上是有序的,单独来看是无序的。因此只有是由最左侧的字段,才能使用索引。

  因为 mysql 在创建联合索引时,首先会对最左边字段排序,也就是第一个字段,然后在保证第一个字段有序的情况下,在排序第二个字段,以此类推。所以联合索引最左列绝对有序,其他字段无序index(a,b,c) 只有使用 a 字段匹配时会用到联合索引

2.7,索引失效的几种情况

1)联合索引不满足最左匹配原则

2)使用 select *,不会走覆盖索引,大概率不会走索引。结果集条数和总数据量的比例,以及索引字段都有关系。老老实实写字段名完事。

3)索引上有计算或者函数, 如

//不走索引
explain select *  from part where (id + 1) >= 1;
//走索引
explain select *  from part where id >= 1;

4)字段类型不同(隐式类型转换)

//(ranking 是 varchar 类型)
//不走索引
explain select id, province, ranking from part where ranking = 1
//走索引
explain select id, province, ranking from part where ranking = '1'

//但是如果字段是数字,匹配值是 string,依然会走索引。mysql发现如果是int类型字段作为查询条件时,它会自动将该字段的传参进行隐式转换,把字符串转换成int类型
select 1 + '1';  //结果是 2
select concat(1 + '1');  //结果是 11

5)like 以 % 开头

//走索引
explain select province, position from part where position like '123';
//走索引
explain select province, position from part where position like '123%';
//不走索引
explain select province, position from part where position like '%123';

6)or 条件的字段,其中一个没有索引,所有索引都失效

//(city 字段无索引,导致索引失效)
//不走索引
explain select province, position from part where position = '123' or city = 'ces1';

//两个字段都有索引,索引生效
//走索引
explain select province, position from part where position = '123' or ranking = '1';

7)两列作比较

//不走索引
explain select * from part where id = m_index;

8)not in 和 not exists

in 和 exists 都可以使用索引, 主键时候 not in 和 not exists 索引都生效,非主键都不可以。
一般用 exists 代替 in,除非 in 的是一个参数列表,exists 无法表示。

9)使用不等于

<>, != 都可能导致普通索引不生效,要看结果集占比,占比较大时候不走索引。

10) is not null

有时候会导致索引失效。

11)order by

某些情况下会导致索引失效。

12,全表扫码速度优于索引的时候。

1-7 索引指定失效,后面几种可能会失效。

3,事务

事务( Transaction)由一次或者多次基本操作构成,或者说,事务由一条或者多条 SQL 语句构成。

3.1,事务控制语句

1)begin transaction;/start transaction; 显式的开启一个事务
2)commit/commit work; 提交事务
3)rollback/rollback work; 回滚事务
4) savepoint identifier; SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;
5) release savepoint identifier; 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常
6) rollback to identifier; 把事务回滚到标记点;
7) SET TRANSACTION; 用来设置事务的隔离机制。(READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE)
8) SET AUTOCOMMIT; 设置自动提交。

3.2,并发事务带来的问题

1)脏读:事务 A 读到事务 B 未提交的数据。
2)不可重复读:事务 A 两次读取之间,事务 B 修改了数据,导致事务 A 的两次读取结果不一致。
3)幻读:与不可重复读类似,只是侧重与 B 事务对数据的删除和增加,不可重复读由于修改数据导致。

3.3,事务的四种隔离机制

隔离级别 脏读 不可重复读 幻读
Read Uncommitted 读未提交 可能 可能 可能
Read Committed 读已提交 不可能 可能 可能
Repeatable Read 可重复读 不可能 不可能 可能
Serializable 可串行化 不可能 不可能 不可能

mysql 默认 Repeatable Read。(因为主从复制的原因,以前 binlog 只有 statement 格式)
项目使用 read committed?

1)在 RR 隔离级别下,存在间隙锁,导致出现死锁的几率比 RC 大得多。
2)在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行!也就是说,RC的并发性高于RR。大部分场景下不可重复读是可以接收的。

查看当前事务隔离机制:

//查看当前事务隔离机制:
show variables like 'transaction_isolation';
SELECT @@tx_isolation;

//修改隔离级别:
//设置read uncommitted级别:
set session transaction isolation level read uncommitted;

//设置read committed级别:
set session transaction isolation level read committed;

//设置repeatable read级别:
set session transaction isolation level repeatable read;

//设置serializable级别:
set session transaction isolation level serializable;

session 表示当前会话,替换未 global 表示全局

4,MySql 锁

4.1,锁的分类

1)加锁机制

  • 乐观锁基于程序实现(版本号),适用于读多写少场景。
  • 悲观锁:认为获取和读写数据时,别人总会修改数据,所以处理过程中需要将数据锁定。

2)加锁属性:

  • 共享锁:其他事务支持读取,不支持增删改。
    SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

  • 排他锁:不支持其他事务增删改查。
    SELECT * FROM table_name WHERE ... FOR UPDATE

3)加锁粒度:

  • 全局锁:让整个库处于只读状态。(做数据库备份)
  • 表锁:表锁是MySQL中最大粒度的锁定机制,会锁定整张表,一般在执行 DDL 语句时会对整个表进行加锁,比如说ALTER TABLE。
  • 页锁: BDB 存储引擎,粒度介于表锁和行锁之间。
  • 行锁:存储引擎自己实现,仅 Innodb 支持。

4)加锁模式:

  • 记录锁(Record Lock):记录锁锁定的是记录中的聚簇索引,需要注意的是 c1=10满足条件的数据并不一定只有一条,所以记录锁也不是只锁定一行记录的锁。

  • 间隙锁(Gap Lock):间隙锁是索引记录之间,或者是第一个索引记录之前或最后一个索引记录之后间隙上的锁。例如, SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;防止其他事务将值15插入到列t.c1中,无论该列中是否已存在此值,因为范围中所有现有值之间的间隙已锁定。

  • 临界锁(Next-Key Locks):临界锁是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合。

  • 意向锁(Intention Locks):意向锁是将锁定的对象分为多个层次, 意向锁意味着事务希望在更细粒度上进行加锁(表锁),完全看不懂。

  • 插入意向锁(Insert Intention Locks):插入意图锁是在行插入之前通过插入操作设置的一种间隙锁。该锁以这样一种方式发出插入意图的信号,即插入到同一索引间隙中的多个事务如果不在间隙中的同一位置插入,则不需要彼此等待。

  • 自增锁(AUTO-INC lock):是一种特殊的表级锁,用于插入具有自增列的表的事务使用

4.2,死锁

  死锁是指2+的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

死锁如何排查

1)死锁日志

//其中 LATEST DETECTED DEADLOCK 部分是对死锁的描述。
show engine innodb status;  

2)查看锁状态变量

show status like 'innodb_row_lock%';

Innodb_row_lock_current_waits:当前正在等待锁的数量
Innodb_row_lock_time:从系统启动到现在锁定总时间长度
Innodb_row_lock_time_avg: 每次等待锁的平均时间
Innodb_row_lock_time_max:从系统启动到现在等待最长的一次锁的时间
Innodb_row_lock_waits:系统启动后到现在总共等待的次数

3)通过事务

//1)、查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX

//2)、查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

//3)、查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

//4)、查询是否锁表
SHOW OPEN TABLES where In_use > 0;

4)开启死锁检测(非常消耗 CPU)

innodb_deadlock_detect=on;

如何处理死锁?

1)查看死锁超时时间,超时自己就停止了,默认 50 s

SHOW VARIABLES LIKE "innodb_lock_wait_timeout";

2)将其中一个事务回滚。
3)直接 kill 线程

show processlist;
kill id;

如何避免死锁?

  • 事务尽可能小,不要将复杂逻辑放进一个事务里。
  • 涉及多行记录时,约定不同事务以相同顺序访问。
  • 业务中要及时提交或者回滚事务,可减少死锁产生的概率。
  • 表要有合适的索引。
  • 可尝试将隔离级别改为 RC

5,存储引擎

//查看数据库的存储引擎:
show engines;

//查看 mysql 数据存储物理文件位置:
show variables like 'datadir';

5.1,Innodb 引擎

  • InnoDB 支持事务操作;(每一条SQL都默认封装成事务,自动提交,会影响速度)
  • InnoDB 支持外键;
  • InnoDB 主键索引是聚集索引(聚簇索引);
  • InnoDB 不保存表的总条数;
  • InnoDB 5.7版本之前不支持全文检索;
  • InnoDB 支持表级锁、行级锁,默认为行级锁;
  • InnoDB 表必须有主键(如果我们没有明确去指定创建主键索引。它会帮我们隐藏的生成一个 6 byte 的 int 型的索引作为主键索引);
  • InnoDB 文件存储方式为.frm文件存储表结构,ibd文件存储数据内容。

5.2,MyISAM 引擎

  • MyISAM 是非聚集索引;
  • MyISAM 有一个变量专门来保存整个表的行数,查询count很快(注意不能加任何 where 条件)
  • MyISAM 支持全文索引;
  • MyISAM 可以被压缩后进行查询操作,节省空间容量;
  • MyISAM 支持表级锁,不支持行级锁;
  • MyISAM 中主键不是必须的;
  • MyISAM 文件存储方式为.frm文件存储表结构,.MYD文件存储数据内容,.MYI文件存储索引文件。

5.3,Innodb 和 Myisam 区别?

1)Innodb 支持事务, Myisam 不支持。
2)Innodb 支持外键,Myisam 不支持。
3)Innodb 主键是聚簇索引,必须要有主键,如果没有显式定义,就会生成一个隐藏的,辅助索引和主键索引直接存在层级关系。Myisam 是非聚簇索引,主键不是必须的,辅助索引和主键索引是平级。
4)Innodb 不保存具体行数,Myisam 用一个变量保存,但是不能加 where 条件。
5)Innodb 支持行级锁,表级锁。Myisam 只有表级锁。

5.4,Innodb 为什么使用 id 作为主键?

  MySQL InnoDB 引擎底层数据结构是 B+ 树,所谓的索引其实就是一棵 B+ 树,一个表有多少个索引就会有多少颗 B+ 树,MySQL 中的数据都是按顺序保存在 B+ 树叶子节点上的。

  MySQL 在底层又是以数据页为单位来存储数据的,一个数据页大小默认为 16k,当然你也可以自定义大小,也就是说如果一个数据页存满了,MySQL 就会去申请一个新的数据页来存储数据。

  如果主键为自增 id 的话,MySQL 在写满一个数据页的时候,直接申请另一个新数据页接着写就可以了。
  如果主键是非自增 id,为了确保索引有序,MySQL 就需要将每次插入的数据都放到合适的位置上。
  当往一个快满或已满的数据页中插入数据时,新插入的数据会将数据页写满,MySQL 就需要申请新的数据页,并且把上个数据页中的部分数据挪到新的数据页上。这就造成了页分裂,这个大量移动数据的过程是会严重影响插入效率的。

  自增id 可以保证每次插入时B+索引是从右边扩展的,可以避免B+树频繁合并和分裂(对比使用UUID而言)。如果使用字符串主键和随机主键,会使得数据随机插入,效率比较差。

6,sql 执行相关

6.1,一条 sql 是怎么执行的?

1)连接器:建立连接
2)分析器:识别关键字,表名及字段名等,并且分析语法。
3)优化器:对 sql 语句进行优化,比如该用什么索引,sql 顺序调整等。
4)执行器:对表权限校验,权限通过才使用引擎提供的接口
5)存储引擎:获取符合的数据。

6.2,sql 执行顺序

from > on > join > where > group by(开始使用 select 中别名) > sum/count/max/avg > having > select > distinct > order by > limit

6.3 为啥建议字段设置不为 null?

1)聚合函数会忽略 null 值, count(*) 是对行数统计,count(name) 是对 name 不为 null 做统计
2)= 号失效,需要用 is null 判断
3)与其他值运算,user表第二条记录age是NULL,所以+1之后还是NULL,name是NULL,进行concat运算之后结果还是NULL
4)!= 会忽略 null 值
5)占用更大的空间,在MySQL里也需要特殊处理。当可为null的列被索引时,每个索引记录需要一个额外的字节。

7,mysql 日志

7.1,redo log

是 Innodb 的事务日志,每次读写数据先写入 Buffer Pool,定期刷到磁盘中,redo 用来保障缓存可以刷新到磁盘中。
(1)修改记录前,先写入 redo 日志。
(2)redo 日志大小固定,形成环形。
(3)crash-safe,mysql 启动时,总是根据 redo log 进行恢复操作。

7.2,undo log

也是 MySql 存储引擎 Innodb 的事务日志,用来做事务回滚。
(1)记录事务开始前要修改数据的原始版本,写入一条与当前操作相反的逻辑日志到 undo 日志中。
(2)undo long 做回滚,redo log 做前滚,数据库实例恢复时,先做前滚,后做回滚。

7.3,bin log

归档日志,与引擎无关。bin log记录了数据库所有DDL和DML操作。默认关闭

//查看 bin log 是否开启:
SHOW VARIABLES LIKE 'log_bin';

//查看 bin log 列表:
show binary logs;

//查看过期日期:
show variables like 'expire_logs_days';

使用场景:主从复制,数据恢复。

三种格式:

1)STATMENT:基于SQL 语句的复制( statement-based replication, SBR ),每一条会修改数据的sql语句会记录到binlog 中 。
  优点:不需要记录每一行的变化,减少了 binlog 日志量,节约了 IO , 从而提高了性能;
  缺点:主从复制时,存在部分函数(如 sleep)及存储过程在 slave 上会出现与 master 结果不一致的情况。

2)ROW:基于行的复制(row-based replication, RBR ),不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了 。
  优点:因此不会发生某些特定情况下的存储过程、函数或者触发器的调用触发无法被正确复制的问题。
  缺点:会产生大量的日志,尤其是alter table 的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中,实际等于重建了表。

3)MIXED:基于STATMENT 和 ROW 两种模式的混合复制(mixed-based replication, MBR ),一般的复制使用STATEMENT 模式保存 binlog ,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 binlog。

7.4,错误日志

收集运行过程中错误信息,默认开启无法关闭。

7.5,查询日志

记录数据库执行的所有命令。默认关闭,开启的话很大。

7.6,慢查询日志

超过 long_query_time 未响应的 sql,默认 10 s。默认关闭。

7.7,中继日志

中继日志用于主从复制架构中的从服务器上,从服务器的 slave 进程从主服务器处获取二进制日志的内容并写入中继日志,然后由 IO 进程读取并执行中继日志中的语句。

8,一些其他问题

8.1,三范式

1)1NF:属性不可分割。
2)2NF:属性完全依赖于主键
3)3NF:任何非主属性不得传递依赖于主属性。

8.2,主从延迟解决方案

1)配合 semi-sync 半同步复制;
2)一主多从,分摊从库压力;
3)强制走主库方案(强一致性);
4)sleep 方案:主库更新后,读从库之前先 sleep 一下;
5)判断主备无延迟方案(例如判断 seconds_behind_master 参数是否已经等于 0、对比位点);
6)并行复制 — 解决从库复制延迟的问题;

8.3,分表分库

1)水平分库:以字段为依据,按照一定的策略(range,hash)将数据分入多个库。
2)水平分表:以字段为依据,按照一定的策略(range,hash)将数据分入多个表。
3)垂直分库:以表为依据,按照业务需求将表拆分为多个库中的表。
4)垂直分表:以表为依据,按照业务需求将表拆分为多个表。

分表分库带来的问题?

1)事务问题
2)分页,排序,函数问题
3)全局主键避重问题
4)数据迁移,扩容问题

数据库分表分库带来的问题

8.4,count(1),count(*),count(列名) 比较?

执行效果

count(1) 忽略所有列,用 1 代表行,不会忽略列值为 null
count(*) 包括所有行,相当于行数,不会忽略列值为 null
count(列名) 只统计列名那一列,null不会被统计。

执行效率:

列名为主键:count(列名) 优于 count(1)
列名不为主键:count(1)优于 count(列名)
如果表只有一个字段,count(*) 最优
如果有主键,count(主键) 最优
多个字段并且没有主键,count(1)最优

8.5,sql 优化

1)整体性能分析,explain 关键字
2)数据库层面的优化,分表分库,以及建表选用合适的数据类型。
3)建立合适的索引,查询尽量命中索引
4)尽量返回无用的字段和记录,不使用 *

8.6,sql 语句分类

DQL:data Query language,数据查询语言(select)
DML:data manipulation language,数据操作语言(insert,delete,update)
DDL:data definition language,数据库定义语言(create,alter,drop,truncate)
DCL:data control language,数据库可控制语言(grant,deny,revoke)

标签:总结,事务,知识,id,索引,Mysql,数据,主键,select
From: https://www.cnblogs.com/cnff/p/17162032.html

相关文章

  • 2022.3.7学习总结
    按照我们敬爱的建民老师的要求,我对我的UI交互界面做了一些优化,包括两个方面,首先是按钮的风格,接着又解决了标题栏的问题。 由于能力有限,暂时设计不出更加漂亮的标题栏,于......
  • 资料分析、图形推理总结
    资料分析:截位直除1.概念截位:从左往右保留前几位,看下一位四舍五入2.运用(1)截几位①选项差距大:截两位②选项差距小:截三位(2)截谁①一步除法:只对分母截位②多步乘除:分子、分母......
  • Starrocks出现Lost connection to MySQL server during query
    背景:在调度中出现这个报错,但是在后台执行的时候是成功的,每次在调度上执行6分钟即360S的时候出现了这个报错,排查后发现使用的nginx代理中设置的timeout设置的是360s,所以......
  • 2023.3.7每日总结
    今天学习了获取系统时间并且使用DatePicker标签自由选择时间<DatePickerandroid:layout_margin="10dp"android:id="@+id/select_time"and......
  • JAVA项目中的常用的异常处理情况总结
    一,JDK中与异常相关的类分析:Java中的异常分类:Throwable类有两个直接子类:Exception:出现的问题是可以被捕获的;Error:系统错误,通常由JVM处理。可捕获的异常又可以分为两......
  • 每日总结3.7
    每日总结:所花时间:5h代码量:0行博客量:1篇————————————~~~~~~刷~~~~~————————————————今天的课程有英语、数据库与python......
  • 3-7总结
    今天针对与昨天的上课测试importjava.util.Scanner;publicclassmain{publicstaticvoidmain(String[]args){Scannercin=newScanner(Syste......
  • 3月07日课后总结
    3/07课后总结模块的简介1.什么是模块? #一系列功能的集合体2.为什么要用模块? #为了提高开发效率3.模块的来源1.内置:python解释器自带的2.第三方:别人......
  • 连上mysql数据库了,先小发表一下
    首先我的mysql是8.0版本的,用的8版本的驱动包就连接失败找不到类,后来换成5版本的就好了。一开始我按照网上的教程,告诉我需要在子线程才能执行jdbc的连接,代码如下所示:r......
  • 2023.3.7每日总结
    开发Android应用也需要以下5步:开发工具安装和配置搭建开发环境在AndroidStudio中,创建第一个项目完成简单Helloworld代码编写编译APK文件,让应用在手机上......