Java学习-数据库MySQL复习

本文详细解析了MySQL的基础知识、索引管理、事务处理、存储引擎InnoDB与MyISAM的区别、慢查询优化策略以及索引的优缺点。涵盖了设计关系数据库、事务隔离级别和并发控制,深入浅出地介绍了存储过程、锁机制和大表优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先给出三个mysql的连接,第一个是面经常见题目背诵,第二个和第三个是mysql系统复习。

面经常见题背诵

mysql背诵版

mysql详解

数据库mysql详解
MySQL 有这一篇就够

mysql学习路线

在这里插入图片描述

如何设计一个关系数据库

如何设计一个关系数据库
关系数据库设计分为两层,一个是程序实例,一个是文件存储。
在这里插入图片描述
程序实例( 管理逻辑存储)
存储管理
缓存机制(优化执行效率)
SQL解析
日志管理
权限划分(多用户管理)
容错机制
索引管理(优化查询效率)
锁管理(支持并发)

mysql存储引擎 InnoDB和MyISAM

Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。**

MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键。

MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。

**Innodb:**更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键。比如OA自动化办公系统。
在这里插入图片描述

索引

图文并茂说MySQL索引——入门进阶必备

索引的数据结构

索引的数据结构有哈希索引和B树索引。
MySQL为什么要用B+树而不用其他树:因为B+树,中间节点用于帮助索引,不存储值,B+树更加矮胖,树高度小。IO次数更少。参考连接

聚集索引(主键索引)

聚集索引的两大特点:
1.使用主键值大小进行记录和页的排序,都是按照主键值升序排列,记录之间是单链表结构,页与页之间是双链表结构。
2.B+树的叶子结点是完整的用户记录,也就是叶子结点存储了所有列的值(包括隐藏列)。
橙色表示主键。最后一行是所以的记录
在这里插入图片描述

非聚集索引(辅助索引/二级索引)

当频繁查询非主键元素C2时,这时为非主键元素C2建立索引就是非聚集索引。有以下特点:
1.B+树的叶子结点存储的不是完整的用户记录,没有全部列的信息,只有c2列和主键列这两个列的值。
2.目录项记录不再是主键+页号,而是c2列+页号。
3.使用记录c2列的大小进行记录和页的排序。不管是用户记录页还是目录页,都是按照c2列的大小升序排列的单链表结构。
蓝色表示C2列的值,绿色是页号
在这里插入图片描述
回表:当非聚集索引查询到了非主键元素。需要获取到整个用户记录时。由于非聚集索引是不完全的用户记录。所以需要根据主键值去查询聚集索引。找到完整的用户记录。

联合索引和最左匹配原则

联合索引就是为两个或以上的非主键元素建立索引。例如按照非主键元素C2,C3联合索引。那么就是B+树把各用户记录和页号按照C2的列进行排序。在C2记录相同的情况下,按照C3列排序。
蓝色是C2,红色是C3,橙色是主键C1。
在这里插入图片描述
最左匹配原则:查询联合索引时,例如联合索引是(a,b,c)。那么先查a则会使用到联合索引。先a后b也可以。按照abc的顺序依次出现就可以调用联合索引。如果先查c再查b则不会使用该联合索引。但是ac也不走。必须是按照a->b->c的顺序才走联合索引。

索引覆盖:如果我频繁查询非主键字段C2,C3。然后为C2,C3建立了联合索引。那么我可以通过查询C2和C3的组合得到整个需要查询的字段。我只需要C2,C3。那么这个时候。联合索引覆盖了我需要的所有字段。则称为索引覆盖 索引覆盖详解

如何定位和优化慢查询

MySQL如何定位慢查询SQL
面试官:如何快速定位慢SQL
如何定位及优化慢sql
1.查询是否开启了慢查询mysql> show variables like ‘%slow%’;
2.设置慢查询时间阈值mysql> show variables like ‘long_query_time’;
3.查看慢查询数目show status like ‘slow_queries’;
4.查看慢查询日志,找到慢sql并用explain来分析
5.MySQLdumpslow分析工具辅助分析。
6.修改sql语句,让sql走索引或者增加新的索引。

索引的优缺点

优点:通过创建唯一性索引,可以保证数据库表中的每一行数据的唯一性。可以加快数据的检索速度。可以加速表与表之间的连接,在使用分组和排序进行检索的时候,可以减少查询中分组和排序的时间。
缺点(索引越多越好吗):创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。索引需要占用物理空间,数据量越大,占用空间越大。会降低表的增删改的效率,因为每次增删改索引,都需要进行动态维护

什么时候需要创建索引:1主键自动建立唯一索引。2频繁作为查询条件的字段应该创建索引。3查询中排序的字段创建索引将大大提高排序的速。4查询中统计或者分组的字段;
什么时候不用创建索引:1频繁更新的字段不适合创建索引,因为每次更新不单单是更新记录,还会更新索引,保存索引文件。2where条件里用不到的字段,不创建索引;3表记录太少,不需要创建索引;4经常增删改的表;数据重复且分布平均的字段,因此为经常查询的和经常排序的字段建立索引。注意某些数据包含大量重复数据,因此他建立索引就没有太大的效果,例如性别字段,只有男女,不适合建立索引。

如何为表字段添加索引

1.添加PRIMARY KEY(主键索引):

ALTER TABLE table_name ADD PRIMARY KEY ( column )

2.添加UNIQUE(唯一索引) :

ALTER TABLE table_name ADD UNIQUE ( column )

3.添加INDEX(普通索引) :
ALTER TABLE table_name ADD INDEX index_name ( column )

4.添加FULLTEXT(全文索引) :
ALTER TABLE table_name ADD FULLTEXT ( column)

5.添加联合索引:
ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 )

事物

第10章讲解事物非常详细
事务: transaction, 一系列要发生的连续的操作

事务安全: 一种保护连续操作同时满足(实现)的一种机制

事务安全的意义: 保证数据操作的完整性

如果SQL语句直接操作文件是很危险的,比如你要给员工涨工资,正在update操作的时候,系统断电了,你就不知道谁已经涨了谁还没涨。因此我们应该利用日志来间接写入。

在这里插入图片描述
MySQL总共5种日志,其中只有redo日志和undo日志与事务有关

日志就相当于数据文件的一个副本,SQL语句操作什么样的记录,MySQL就会把这些记录拷贝到undo日志,然后增删改查的操作就会记录到redo日志,最后把redo日志和数据库文件进行同步就行了。即使同步过程中断电了,有了redo日志的存在,重启MySQL数据库之后继续同步数据,同步成功后我们修改的数据就真正同步到数据库里面了,有事务的数据库抵抗风险的能力变强了。

RDBMS=SQL语句+事务(ACID)

事务是一个或者多个SQL语句组成的整体,要么全部执行成功,要么全部失败。

事物的四大特性ACID

A: Atomic原子性,一个事物中的所有操作要么全部完成,要么全部失败。事物执行后,不允许停留在中间某个状态。

C: Consistency一致性,不管在任何给定的时间,并发事务有多少,事务必须保证运行结果的一致性。事务可以并发执行,但是最终MySQL却串行执行。

怎么保证一致性?

阻止事务之间相互读取临时数据

I: Isolation隔离性,每个事务只能看到事务内的相关数据,别的事务的临时数据在当前事务是看不到的。隔离性要求事务不受其他并发事务的影响,在给定时间内,该事务是数据库运行的唯一事务。

D: Durability持久性,事务一旦提交,结果便是永久性的。即便发生宕机,仍然可依靠事务日志完成数据持久化。

脏读、不可重复读、幻读的区别(并发事物带来哪些问题)

如果事务没有隔离性,按照不受控制的顺序并发读取和修改数据,想像一下会出现哪些问题?

脏读:事物A读了事物B更改的数据D,但是事物B没有将更改的数据D提交,然后事物B出现了其他操作又回滚了。那么事物A使用了D就是脏数据。是不应该出现的,违反了一致性。

不可重复读:一个事物前后两次读取的同一数据不一致。事物A读取了数据D=9,但是事物B把数据D修改为D=10并且提交了。事物A再读取的时候数据D变成了D=10。注意,不可重复读和脏读的区别就是,脏读的数据会回滚,不可重复读会把数据提交,脏读的数据是无效的,而不可重复读因为事务2的提交,数据是有效的

幻读:指一个事务两次查询的结果集记录数不一致。事物A读取了表T的所有数据,但是事物B又向表T中添加或者删除了数据集。导致事物A再次查询的时候,多出来或者少了数据,像出现了幻觉。但是幻读的数据是有效的

幻读和不可重复读的数据都是有效的,是因为都进行了COMMIT提交。而脏读没有提交,所以是无效的。

事物的隔离级别

在某些特定场合,我们又想让事务之间读取到一些临时数据,这就需要修改事务的隔离级别
在这里插入图片描述

  1. read uncommitted
    场景一:比如买票的场景,逢年过节都需要买票回家,假如A和B都在买同一辆车的车票,此时还剩最后一张票,A点击购买,但是还没付款提交,因为查看不到事务之间的临时数据,所以B查看时,也还剩一张票,于是B点击购买,立即付款提交,结果A就会购买失败。所以理想的情况应该是,当A点击购买去付款时,B应该看得到这个临时数据,显示没有票才对。这种场景会出现脏读、幻读、不可重复读情况,隔离性最低,并发性最高
    在这里插入图片描述

  2. read committed
    场景二:银行转账的场景,A事务执行往Scott账户转账1000的操作,B事务执行扣除Scott账户100块的操作,如果A能读取到B事务未提交的数据,那么转账后就会修改为5900,而此时因为各种原因需要回滚支出100元的这个操作,此时账户就只有5900块了,凭空消失100块,所以只有A事务读取到B事务提交后的数据才能保证转账的正确性。这种场景就和买票的场景完全不同。这种场景是会出现幻读和不可重复读的。
    在这里插入图片描述

  3. repeatable read(mysql默认隔离级别)
    场景三:你在淘宝或者京东等电商,点击购买,选好收货地址之类的之后,点击提交订单,就会让你输入支付密码支付,此时显示的价格是undo日志的价格,如果此时卖家涨价,你购买的还是涨价之前的价格,这种场景就是可重复读。可重复读不会出现脏读、不可重复读的情况,因为事务1读取不到事务2对数据的修改。对于幻读,这里只有靠临键锁才能保证不出现幻读的问题。
    在这里插入图片描述

  4. serializable
    由于事务并发执行所带来的各种问题,前三种隔离级别只适用于在某种业务场景中,凡事序列化的隔离性,让事务逐一执行,就不会产生上述问题了。但是序列化的隔离级别使用的特别少,它让事务的并发性大大降低。可重复读不会出现幻读、脏读、不可重复读的情况,因为事务1读取不到事务2对数据的修改。隔离性最高,并发性最低,其实就是没有并发,所有事务按照顺序执行。

在这里插入图片描述

数据库事物的实现原理

数据库–事物实现原理
数据库事务的概念及其实现原理

1.事务的原子性是通过 undo log 来实现的
2.事务的持久性性是通过 redo log 来实现的
3.事务的隔离性是通过 (读写锁+MVCC)来实现的
4.而事务的终极大 boss 一致性是通过原子性,持久性,隔离性来实现的!!!

原子性的实现

一个事务必须被视为不可分割的最小工作单位,一个事务中的所有操作要么全部成功提交,要么全部失败回滚,对于一个事务来说不可能只执行其中的部分操作,这就是事务的原子性。通过回滚操作。所谓回滚操作就是当发生错误异常或者显式的执行rollback语句时需要把数据还原到原先的模样,所以这时候就需要用到undo log来进行回滚

持久性的实现

由于MYSQL是将表存在磁盘上,通过buffer pool的结构加速读取。但是断电或者断开连接等问题会使得数据丢失。所以需要redo log来实现持久性。如果断电,可以从redo日志中对操作进行恢复。
在这里插入图片描述

隔离性的实现

在MySQL的四个级别中分别对应不同的并发性。

并发控制技术是实现事务隔离性以及不同隔离级别的关键,实现方式有很多,按照其对可能冲突的操作采取的不同策略可以分为乐观并发控制和悲观并发控制两大类。

乐观并发控制:对于并发执行可能冲突的操作,假定其不会真的冲突,允许并发执行,直到真正发生冲突时才去解决冲突,比如让事务回滚。

悲观并发控制:对于并发执行可能冲突的操作,假定其必定发生冲突,通过让事务等待(锁)或者中止(时间戳排序)的方式使并行的操作串行执行。

1.READ UNCOMMITTED:完全不加读锁,但写加锁。这样就能读写并行
在这里插入图片描述
优点:读写并行,性能高, 缺点:造成脏读
2.READ COMMITTED:采用了读写分离机制,使用了排它锁,读取数据不加锁而是使用了MVCC(多版本并发控制)机制,读取的时候有多个副本。每个副本都有版本号。

由于快照隔离导致事务看不到其他事务对数据项的更新,为了避免出现丢失更新问题,可以采用以下两种方案避免:
a.先提交者获胜:对于执行该检查的事务T,判断是否有其他事务已经将更新写入数据库,是则T回滚否则T正常提交。
b.先更新者获胜:通过锁机制保证第一个获得锁的事务提交其更新,之后试图更新的事务中止。

共享锁(S锁) :(插入/修改/删除)资源获取S锁之后,能加S锁,不能加X锁
排它锁(X锁) : 资源加上X锁之后,不能加S锁,也不能加X锁

在这里插入图片描述
3.REPEATABLE READ(Mysql默认隔离级别):分别是采用读写锁以及MVCC。
读写锁实现:优点:实现起来简单, 缺点:无法做到读写并行
在这里插入图片描述
MVCC实现:优点:读写并行 缺点:实现的复杂度高
在这里插入图片描述
4.SERIALIZABLE:该隔离级别理解起来最简单,实现也最单。在隔离级别下除了不会造成数据不一致问题,没其他优点。
在这里插入图片描述

一致性的实现

通过回滚,以及恢复,和在并发环境下的隔离做到一致性

数据库总是从一个一致性的状态转移到另一个一致性的状态.

下面举个例子:zhangsan 从银行卡转400到理财账户

starttransaction;

selectbalance frombank wherename=“zhangsan”;

// 生成 重做日志 balance=600

updatebank setbalance = balance - 400;

// 生成 重做日志 amount=400

updatefinance setamount = amount + 400;

commit;

1.假如执行完 update bank set balance = balance - 400;之发生异常了,银行卡的钱也不能平白无辜的减少,而是回滚到最初状态。

2.又或者事务提交之后,缓冲池还没同步到磁盘的时候宕机了,这也是不能接受的,应该在重启的时候恢复并持久化。

3.假如有并发事务请求的时候也应该做好事务之间的可见性问题,避免造成脏读,不可重复读,幻读等。在涉及并发的情况下往往在性能和一致性之间做平衡,做一定的取舍,所以隔离性也是对一致性的一种破坏。

在这里插入图片描述
开销、加锁速度、死锁、粒度、并发性能

表锁:开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般

表锁

表锁和行锁锁的粒度不一样,表锁锁住的是一整张表,
表锁的优势:开销小;加锁快;无死锁
表锁的劣势:锁粒度大,发生锁冲突的概率高,并发处理能力低
加锁的方式:自动加锁。查询操作(SELECT),会自动给涉及的所有表加读锁,更新操作(UPDATE、DELETE、INSERT),会自动给涉及的表加写锁。也可以显示加锁:

共享读锁:lock table tableName read;

独占写锁:lock table tableName write;

批量解锁:unlock tables;

行锁的模式

行锁锁住的是表中的一行数据,行锁是开销最大的锁策略,表锁是开销最小的锁策略。

行锁的劣势:开销大;加锁慢;会出现死锁
行锁的优势:锁的粒度小,发生锁冲突的概率低;处理并发的能力强
加锁的方式:自动加锁。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,InnoDB不会加任何锁;当然我们也可以显示的加锁:

InnoDB实现了以下两种类型的行锁。
共享锁(s):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。
另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。
意向共享锁(IS):事务打算给数据行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
如果一个事务请求的锁模式与当前的锁兼容,InnoDB就请求的锁授予该事务;反之,如果两者两者不兼容,该事务就要等待锁释放。
意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及及数据集加排他锁(X);对于普通SELECT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会任何锁;事务可以通过以下语句显示给记录集加共享锁或排锁。
共享锁(S):SELECT * FROM table_name WHERE … LOCK IN SHARE MODE
排他锁(X):SELECT * FROM table_name WHERE … FOR UPDATE
用SELECT … IN SHARE MODE获得共享锁,主要用在需要数据依存关系时确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作。但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT … FOR UPDATE方式获取排他锁。
参考连接

**自增锁:**在MYSQL 5.1.22版本前,自增列使用AUTO_INC Locking方式来实现,即采用一种特殊的表锁机制来保证并发插入下自增操作依然是串行操作,为提高插入效率,该锁会在插入语句完成后立即释放,而不是插入语句所在事务提交时释放。该设计并发性能太差,尤其在大批量数据在一条语句中插入时(INSERT SELECT ), 会导致该语句长时间持有这个“表锁”,从而阻塞其他事务的插入操作。

在MYSQL 5.1.22版本开始,InnoDB存储引使用一种轻量级互斥锁(Mutex)来控制自增列增长,并提供innodb_autoinc_lock_mode参数来控制。

首先,该参数仅在InnoDB引擎下生效,myisam引擎下,无论什么样自增id锁都是表级锁
0:traditonal (每次都会产生表锁)
1:consecutive (mysql的默认模式,会产生一个轻量锁,simple insert会获得批量的锁,保证连续插入)
2:interleaved (不会锁表,来一个处理一个,并发最高)

自增方式分类:1.INSERT-LIKE:指所有的插入语句,比如 INSERT、REPLACE、INSERT…SELECT、REPLACE…SELECT,LOAD DATA等。2.Simple insert:指在插入前就能确定插入行数的语句,包括INSERT、REPLACE,不包含INSERT…ON DUPLICATE KEY UPDATE这类语句。3.Bulk inserts:指在插入前不能确定得到插入行的语句。如INSERT…SELECT,REPLACE…SELECT,LOAD DATA. 4.Mixed-mode inserts:指其中一部分是子增长的,有一部分是确定的。

1.innodb_autoinc_lock_mode=0 传统锁定模式, 5.1.22之前的方式,也就是所有INSERT-LIKE操作都用AUTO-inc locking。
2.innodb_autoinc_lock_mode=1 连续锁定模式,这个参数是5.1.22之后出现的也是之后的默认值,对于SIMPLE INSERT,使用轻量级互斥锁,对于BULK INSERT,使用AUTO-inc locking。
3.innodb_autoinc_lock_mode=2 交错锁定模式,指不管什么情况都使用轻量级互斥的锁,效率最高,但是复制只能使用row-basereplication,因为statement-base replication会出现问题
参考连接

记录锁(行锁)

记录锁是锁住记录,锁住索引记录,而不是真正的数据记录

1.锁是非主键索引,会在索引记录上加锁后,在去主键索引上加锁
2.表上没有索引,会在隐藏的主键索引上加锁
3.如果要锁的列没有索引,进行全表记录加锁

间隙锁

编程的思想源于生活,生活中的例子能帮助我们更好的理解一些编程中的思想。
生活中排队的场景,小明,小红,小花三个人依次站成一排,此时,如何让新来的小刚不能站在小红旁边,这时候只要将小红和她前面的小明之间的空隙封锁,将小红和她后面的小花之间的空隙封锁,那么小刚就不能站到小红的旁边。
这里的小红,小明,小花,小刚就是数据库的一条条记录。
他们之间的空隙也就是间隙,而封锁他们之间距离的锁,叫做间隙锁。
参考链接

临键锁(Next-Key锁)

是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。
注:临键锁的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,临键锁则也会失效。

三者之间的区别
Record Lock:记录锁,单个行记录上的锁。
Gap Lock:间隙锁,锁定一个范围,但不包括记录本身。
Next-Key Lock:临键锁,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,可以解决幻读的问题。
mysql Innodb 三种行锁(记录锁、间隙锁与临键锁)

插入意向锁(Insert Intention Locks)

(1)插入意向锁是一种Gap锁,不是意向锁,在insert操作时产生。
(2)在多事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等待。
(3)假设有一个记录索引包含键值4和7,不同的事务分别插入5和6,每个事务都会产生一个加在4-7之间的插入意向锁,获取在插入行上的排它锁,但是不会被互相锁住,因为数据行并不冲突。
(4)插入意向锁不会阻止任何锁,对于插入的记录会持有一个记录锁。
参考链接

大表优化

第一优化你的sql和索引;
第二加缓存,memcached,redis;
第三以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以用三方工具,第三方工具推荐360的atlas,其它的要么效率不高,要么没人维护;
第四如果以上都做了还是慢,不要想着去做切分,mysql自带分区表,先试试这个,对你的应用是透明的,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑,在这里就不多说了;
第五如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统;
第六才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;

非常的复杂的全文介绍
Mysql对于千万级别大表要怎么优化
读写分离:也是目前常用的优化,从库读,主库写,一般不要采用双主或多主引入很多复杂性,尽量采用文中的其他方案来提高性能。同时目前很多拆分的解决方案同时也兼顾考虑了读写分离
在这里插入图片描述
分布式ID:
分库分表后id主键如何处理
在这里插入图片描述
**雪花算法:**我们可以换个角度来对分布式ID进行思考,只要能让负责生成分布式ID的每台机器在每毫秒内生成不一样的ID就行了。

snowflake是twitter开源的分布式ID生成算法,是一种算法,所以它和上面的三种生成分布式ID机制不太一样,它不依赖数据库。

核心思想是:分布式ID固定是一个long型的数字,一个long型占8个字节,也就是64个bit,原始snowflake算法中对于bit的分配如下图:
在这里插入图片描述
第一个bit位是标识部分,在java中由于long的最高位是符号位,正数是0,负数是1,一般生成的ID为正数,所以固定为0。
时间戳部分占41bit,这个是毫秒级的时间,一般实现上不会存储当前的时间戳,而是时间戳的差值(当前时间-固定的开始时间),这样可以使产生的ID从更小值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年
工作机器id占10bit,这里比较灵活,比如,可以使用前5位作为数据中心机房标识,后5位作为单机房机器标识,可以部署1024个节点。
序列号部分占12bit,支持同一毫秒内同一个节点可以生成4096个ID

mysql存储过程

存储过程(Stored Procedure):是一组为了完成特定功能的SQL语句集。经过编译后存储在数据库中,用户通过指定的存储过程名字并给定参数来调用执行。相当于一个函数。

事物:相当于一个进程,多进程执行数据库操作。
存储过程:也是代码段,相当于函数。
触发器:也是一段代码段,特定条件触发了之后执行。

存储过程是数据库的一个重要的功能,MySQL 5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL 5.0开始支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。

MySQL存储过程的创建
语法
CREATE PROCEDURE 过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 …] 过程体

DELIMITER //
CREATE PROCEDURE myproc(OUT s int)
BEGIN
SELECT COUNT(*) INTO s FROM students;
END
//
DELIMITER ;

一条语句在mysql中的执行过程

一条SQL语句在MySQL中执行过程全解析
MySQL 主要分为 Server 层和引擎层,Server 层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog 只有 InnoDB 有。

引擎层是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。
SQL 等执行过程分为两类,一类对于查询等过程如下:权限校验—》查询缓存—》分析器—》优化器—》权限校验—》执行器—》引擎

对于更新等语句执行流程如下:分析器----》权限校验----》执行器—》引擎—redo log prepare—》binlog—》redo log commit

连接器: 身份认证和权限相关(登录 MySQL 的时候)。
查询缓存: 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。
分析器: 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
优化器: 按照 MySQL 认为最优的方案去执行。
执行器: 执行语句,然后从存储引擎返回数据。

在这里插入图片描述
重做日志(redo log):确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。

回滚日志(undo log)保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读

二进制日志(binlog):用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。
用于数据库的基于时间点的还原。

MySQL日志系统:redo log、binlog、undo log 区别与作用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值