download:2022升级百度大牛带你结合实践重学C++完结无密含资料
一条SQL语句从头到尾
1.一段SQL是怎样降生的?
SQL语句都降生在客户端。生成一条SQL主要有两种方式,一种是开发人员本人手工编写,另一种是相关的ORM框架自动生成。普通MySQL运转过程中收到的SQL大多是ORM框架生成的,比方Java中的MyBatis和Hibernate框架。
同时,SQL生成的机遇普通与用户的恳求有关。当用户在系统中执行操作时,通常会生成一条SQL。例如,我们在阅读器上输入以下URL:
此时会先恳求掘金的效劳器,然后掘金内部完成中的ORM框架会依据恳求的参数生成一条SQL,相似于下面的伪SQL:
select * from金爵_article其中userid = 862486453028888
这个SQL大致意义是:依据用户恳求的“作者ID”,查询掘金数据库文章表中该作者的一切文章信息。
从上面的案例能够明显觉得到,在用户阅读器上看到的数据普通来自于数据库,而数据库执行的SQL来自于用户的操作。这两者是互补的,包括任何写操作(添加、删除、更改),实质上也会转换成SQL的片段。让我举一个简单的例子:
恳求URL(恳求URL)
https://www.xxx.com/user/regi...
恳求参数(恳求参数)
{
User_name:“竹子爱熊猫”,
user _ pwd:“123456”,
用户_性别:“男”,
用户_电话:“18888888888”,
......
}
这里对用户密码的处置不够严谨,不做加密也不用在意~
复制代码
例如,在上述用户注册的状况下,当用户点击网页上的“注册”按钮时,将向目的网站的效劳器发送post恳求,然后将依据恳求参数生成一条SQL,如下所示:
insert into table_user(用户名,用户密码,用户性别,用户电话,....)
价值观(“竹子爱熊猫”、“123456”、“男”、“188888888”,...);
复制代码
也就是说,一条SQL的降生源于一个用户的恳求。在开发程序时,SQL的普通逻辑会由业务层的代码决议,而详细的SQL语句会依据用户的恳求参数和事前定制的“SQL骨架”做出。当然,在Java程序或者其他言语编写的程序中,只能生成SQL,SQL的真正执行需求数据库来完成。
第二,SQL在执行之前将阅历的一个过程
经过上一步,一个完好的SQL就降生了。为了让SQL正常执行,我们将首先取得一个数据库衔接对象。上一篇关于MySQL架构的文章,曾经讲过MySQL的衔接层有一个叫“衔接池”的小工具的维护,不过置信大家都接触过这个东西,比方C3P0,德鲁伊,DBCP等等在Java里。
至此,我们能够在这里考虑一个问题。数据库维护本人的衔接池,为什么我们还需求在MySQL客户端维护一个数据库衔接池?接下来我们聊聊。
2.1、数据库衔接池的必要性
众所周知,当你要用Java创立数据库衔接时,首先会读取配置文件中的衔接地址、账号密码等信息,然后发起网络恳求,依据配置的地址信息获取数据库衔接对象。在这个过程中,由于触及到网络恳求,此时必然会阅历TCP三次握手的过程。同时,在取得衔接对象并完成SQL操作后,将释放数据库衔接。这时分就需求阅历TCP挥舞四次的过程。
从上面的描绘中能够明晰地感知到,Java中创立和关闭数据库衔接的过程实践上消耗了大量的本钱,而且程序上线后,还需求频繁的数据库操作。所以,假如每次操作数据库都取得一个新的衔接对象,那么整个Java程序至少有四分之一的时间要做TCP三次握手/四次wave的工作,对整个系统的结果不可思议。....
正是由于以上缘由,才呈现了众所周知的“数据库衔接池”。“数据库衔接池”的思想和“线程池”是一样的,会把数据库衔接到这个珍贵的资源上,用池技术来维护这个资源。也意味着以后需求停止数据库操作时,不需求本人树立衔接,而是能够直接从“数据库衔接池”中获取,用完之后放回衔接池,到达重用的效果。
当然,衔接池中维护的衔接对象不会不断存在。当长时间不执行SQL操作时,衔接池也会销毁这些衔接对象,必要时再重新创立。但是什么时分创立,什么时分销毁,限制衔接数等等,都是交给衔接池来完成,不需求开发者本人关注。
好了~,回到前面抛出的问题,为什么需求用MySQL衔接池在客户端维护一个衔接池?
这个问题置信每个人心里都有一些答案。缘由很简单。两者都运用池化技术来重用资源,俭省开支,进步性能,但针对的方向不同。
MySQL的衔接池主要是为了重用线程,由于每一个数据库衔接都会被MySQL中的一个线程维护,而每一次衔接对象分配给一个客户端,都需求阅历创立线程、分配堆栈空间这样繁重的工作...这个过程需求时间,资源开支也不小,所以MySQL经过运用池化技术来处理这些问题。
客户端的衔接池主要是为了重用数据库衔接,由于每一个SQL操作都需求阅历TCP三次握手/四波的过程,同样耗时耗力,占用资源。所以也采用了池化技术来处理这个问题。
其实也能够这样了解,MySQL衔接池维护的是工作线程,而客户端衔接池维护的是网络衔接。
2.2.在执行SQL之前会发作什么
回到本文的主题,当生成完好的SQL时,我们将首先尝试在衔接池中获取一个衔接对象。接下来会发作什么?
在尝试从衔接池中获取衔接时,假如此时衔接池中有闲暇的衔接,能够直接获取重用。但假如不是,你首先要判别当前池中的衔接数能否到达了最大数量。假如衔接数已满,当前线程需求等候其他线程释放衔接对象。假如没有,您能够直接创立一个新的数据库衔接来运用。
假定此时衔接池中没有闲暇的衔接,需求再次创立新的衔接,那么首先会发起一个网络恳求来树立衔接。
①首先,将考证客户端的用户名和密码能否正确:
假如用户名不存在或密码错误,将抛出错误代码1045和错误音讯。
假如用户名和密码经过考证,请转到步骤②。
②肯定MySQL衔接池中能否有闲暇线程:
存在:直接从衔接池中分配一个闲暇线程来维护当前客户端的衔接。
否:创立一个新的工作线程(映射内核线程,分配堆栈空间...).
worker线程会先查询MySQL本人的用户权限表,获取当前登录用户的权限信息,并停止受权。
至此,执行SQL前的准备工作曾经完成,执行SQL的通道曾经翻开。下一步是准备执行SQL语句,工作线程将等候客户端传送SQL。
三。SQL语句是如何在数据库中执行的?
经过衔接层的一系列工作,客户端会经过衔接发送要执行的SQL语句,然后由MySQL效劳层停止处置。但是依据用户的操作不同,MySQL执行SQL语句时会有一些区别,SQL语句指的是读操作和写操作。这两条SQL语句的执行过程是不同的。我们先来看看select语句的执行过程。
3.1.一个查询SQL的执行过程
在剖析查询SQL的执行过程之前,我们先模仿一个案例停止后续剖析:
- SQL语句
Select id fromZZ _ user
其中user sex =男性,user_name =竹四号";
-表格数据
-
-
-
-
-
-
-
- +
|用户标识|用户名|用户性别|用户电话|
- +
-
-
-
-
-
-
-
-
-
-
-
-
-
- +
| 1 |竹① |男| 1888888888 |
| 2 |竹② |男| 1358888888 |
| 3 |竹③ |男| 1568888888 |
| 4 |熊猫① |女| 1348888888 |
| 5 |熊猫② |女| 1858888888 |
| 6 |竹④ |男| 17777777 |
| 7 |熊猫③ |女| 166666666 |
- +
-
-
-
-
-
-
-
-
-
-
-
-
-
- +
-
-
-
-
-
-