日记 - Mysql数据库的基础知识一

  最近有人问了个数据库的问题,我不懂,然后我忽然发现我对Mysql数据库的结构一无所知,只会一些配置和sql。

  正好公司有数据库的书,看一看,了解了解。

  我自己反思Mysql数据库结构时,第一反应是,它应该是一个服务,因为不管在windows上还是linux上,它都会在后台有一个进程,它是一项服务,而且有地址有端口,我觉得它的存在形式会不会就像tomcat一样。

MySQL逻辑架构

  直接上图,mysql数据库的逻辑架构图


  如上图所示,这个结构分为3层,客户端层、中间层、存储引擎层。

  

  一,客户端层,并不是MySQL所独有的,大多数基于网络的客户端/服务器的工具或者服务都有类似的架构。比如链接处理、授权认证、安全等等。书里并未举例,我个人理解就类似JDBC,以及其他能用于连接MySQL服务器的工具,包括MySQL自己的客户端在内。

  二,中间层,这个中间层是我自己取的名字,书里就叫第二层架构。大多数MySQL的核心服务功能都在这一层,包括查询解析、分析、优化、缓存以及所有的内置函数(例如,日期、时间、数学和加密函数),所有跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。

  三,存储引擎。存储引擎复杂MySQL中数据的存储和提取。和GNU/Linux下的各种文件系统一样,每个存储引擎都各有优劣。服务器通过API与存储引擎进行通信。这些接口屏蔽了不同存储引擎之间的差异,使得上层的查询过程看不到这些差异(个人觉得一些问题都会因此而看不到)。存储引擎API包含十几个底层函数,用于执行诸如“开始一个事务”或者“根据逐渐提取一行记录”等操作。但存储引擎不会去解析SQL(InnoDB例外它会解析外键定义,因为MySQL服务器本身没实现该功能,MySQL本身默认存储引擎就是InnoDB),不同存储引擎之间也不会互相通信,而只是简单地响应上层服务器的请求。

连接安全与管理

  这个就是我被问倒的地方,提问者说:“重复请求时  返回的数据   到数据持久层是什么情况”。上面这是原话。其实他自己不能把自己的问题描述清楚,但是我通过他的问题看到自己的不足。重复请求时,这个请求到了数据库端,数据库是怎么处理的,怎么个流程,真的不知道,别说重复,正常请求都不知道。

  每个客户端链接都会在服务器进程中拥有一个线程,这个连接的查询智慧在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。服务器会负责缓存线程,因此不需要为每一个新建的链接创建或者销毁线程(注:MySQL5.5或者更高的版本提供了一个API,支持线程池(Thread-Pooling)插件,可以使用池中少量的线程来服务大量的连接)

  当客户端连接到MySQL服务器时,服务器需要对其进行认证。认证基于用户名、原始主机信息和密码。如果使用了安全套接字(SSL)的方式连接,还可以使用X.509证书认证。一旦客户端连接成功,服务器会继续验证该客户端是否具有执行某个特定查询的权限(例如对某数据库的某表执行查询语句)。

优化与执行

  MySQL会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。用户可以通过特殊的关键字提示(hint)优化器,影响他的决策过程。也可以请求优化器解释(explain)优化过程的各个因素,使用户可以知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户重构查询和schema、修改相关配置,使应用尽可能高效运行。

  对于SELECT语句,在解析查询之前,服务器会先检查查询缓存(Query Cache),如果能够在其中找到对应的查询,服务器就不必再执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。

并发控制

  无论何时,只要有多个查询需要在同一时刻修改数据,都会产生并发控制的问题。描述一下锁的概念:读锁是共享的,或者说是互相不阻塞的。多个客户可以在同一时刻读取同一个资源,而互不干扰。写锁则是排他的,一个写锁会阻塞其他的写锁和读锁,这是安全策略的考虑,防止其他用户读取正在写入的同一资源。另外,写锁也比读锁有更高的优先级,因此一个写锁请求可能会被插入到读锁列队的前面

  锁粒度,一种提高共享资源并发性的方式就是让锁定对象更有选择性。尽量只锁定需要修改的部分数据,而不是所有资源。相同资源下,锁定的数据量越少,系统的并发程度越高,只要互相不冲突即可。

  加锁需要消耗资源,锁的各种操作,包括获得锁、检查锁是否已经解除、释放锁等,都会增加系统开销。所谓的锁策略就是在锁的开销和数据的安全性之间寻求平衡。

  MySQL提供了多种选择,每种MySQL存储引擎都可以实现自己的锁策略和锁粒度。同时MySQL中有两种最重要的锁策略:表锁行级锁

  表锁是MySQL中最基本的策略锁,也是开销最小的策略。它会锁定整张表。一个用户在对表进行写操作(插入、删除、更新等)前,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。

  行级锁可以最大程度的支持并发处理(同时也带来了最大的锁开销)。行级锁只在存储引擎层实现,而MySQL服务器层没有实现。服务器层完全不了解存储引擎中的锁实现。

  

  

猜你喜欢

转载自lcl088005.iteye.com/blog/2249164