SQL Server 原理
在讲SQLSERVER内部原理的之前,我觉得非常有必要向大家介绍一下SQLSERVER的历史。 让我们站在1999年,看看计算机数据库业界到底处于什么状态。 1999年,Oracle已经于1998年9月发布了Oracle 8i(可能中文版在1999年才来到中国)。Oracle 8i支持用JAVA编写存储过
在讲SQLSERVER内部原理的之前,我觉得非常有必要向大家介绍一下SQLSERVER的历史。
让我们站在1999年,看看计算机数据库业界到底处于什么状态。
1999年,Oracle已经于1998年9月发布了Oracle 8i(可能中文版在1999年才来到中国)。Oracle 8i支持用JAVA编写存储过程,支持XML,支持Linux。
1999年1月,SQLSERVER7正式发布。SQLSERVER7重构了整个数据库引擎(相当于重写了SQLSERVER)。SQLSERVER第一次完整性的支持了行锁(有没有搞错,过去人是怎么使用数据库产品的。1988年,Oracle6就支持行锁。另外1988年,Oracle就开始研发ERP产品。谁说Oracle是ERP门外汉,可以参考这个)。
看看他们俩的前一个版本。如果你入行比较晚(2000年以后),可能对以下文字更感到惊讶。
1992年,Oracle7发布。有了存储过程、触发器、引用完整性校验、分布式事务处理。(天哪,Oracle7才有了这些东西)。
1995年,SQLSERVER6发布。SQLSERVER6是微软真正意义上的第一个数据库产品(真是爆料,大家没想到SQLSERVER6才是微软第一个数据库产品,那版本6之前的5、4、3、2、1是怎么度过的)。因为1994年,微软和Sybase掰了(Sybase是第一个运行于PC上的C/S数据库产品)。微软为了进入数据库产品领域,自己又没有经验,于是和Sybase一起合作(当时微软是全世界第一大软件公司,微软1986年上市。Sybase有产品,缺钱。微软缺产品,有钱。于是一拍即合)。直到1994年,微软也不需要Sybase了(已经学会了数据库技术),Sybase也感觉微软太狼子野心,,于是合作分裂。微软开始自己做自己的数据库。
历史说完。我们言归正传。
很多入门级做管理软件的,SQL语句玩的熟练,从子查询到Having到交叉表统计SQL都能做出来,甚至存储过程能写2000多行,游标、自定义函数、触发器、约束用的眼花缭乱。再入点门,在SQL查询器中可以使用SQL分析优化索引,用SQL Profile可以跟踪SQL,甚至在性能查看器中监测SQLSERVER内存、CPU、线程、I/O的运行状态,甚至为自己会使用DBCC而沾沾自喜。
你是如此熟悉SQLSERVER,又是对SQLSERVER如此陌生。
我今天就用架构的角度来给大家分析一下SQLSERVER架构和原理。短短一篇博文肯定只能面上的多一些,深一层的可能需要连载数篇文章甚至一块大砖头书才能讲完整。不过,我希望我的博文能够抛砖引玉,使大家能从一个过去没有想过的角度去看SQLSERVER。
SQLSERVER,作为一个数据库产品,我个人认为,最重要的就是两大块:存储引擎和查询引擎。
其他的日志、事务、锁、索引等等都是围绕他们来工作的。
SQLSERVER是C/S产品,所以一条SQL语句要让SQLSERVER执行,必须要传输到SQLSERVER服务器端。传输,我们当然知道需要NetBEUI、TCP/IP等等网络传输协议。但是光有这些还不行。客户端如何发,服务器端如何收,如何确认发的和收的正确完整,如何确实发的和收的已经结束,如何发和收能跨越各种网络协议(如UNIX和WINDOWS和NOVELL通讯),如何保证数据安全校验,如何保证数据收发是同步还是异步,就需要在网络传输协议之上再构造一层协议。SQLSERVER既支持IPC机制,也支持RPC机制。你想想你的管理软件开发平台是否有这一层。当然,现在的消息服务器已经专业的提供了这一机理,可靠的、安全的、高效的、异步的、消息压缩、消息拆分、智能路由、集群,跨越不同的操作系统、不同的编程语言、不同的通讯协议、不同的硬件平台的消息数据传输。可能你过去不了解消息中间件,通过这一案例可以知道消息中间件的用途。
SQL语句被可靠无误的发送到了服务器端,SQLSERVER引擎中第一个模块就来接待这个SQL数据。这个模块的名字叫:Open Data Services。它监听新的连接;清除失败连接;将结果集、消息和状态返回给客户端。
SQLSERVER客户端和服务器端之间传输数据,数据包是有格式的。在SQLSERVER中被称为tabular data stream。这个数据流是令牌控制客户端和服务器端对话(否则,客户端说了N句话,服务器端返回N句话,没有令牌就混在一起了,不知道哪个回答是对应哪个请求的)。我们往往不能直接和Open Data Services打交道,把数据放进来。而是我们必须通过ODBC、ADO或DB-Library来发送tabular data stream。而SQLSERVER返回的数据结果,也是通过这些ODBC之类发回tabular data stream。你看看SQLSERVER设计的多巧妙,一个通用数据访问接口屏蔽了你和SQLSERVER之间,就如同WINDOWS API屏蔽了内核让你无法访问,就如同DirectX屏蔽了UI和外设的操控。
SQL语句-ODBC-编码成tabular data stream-IPC或RPC-网络协议-IPC或RPC-解码tabular data stream-ODBC-Open Data Services。
Open Data Services监测客户端连接。如果并发太多,它会创建连接,如果服务完,它会自己维护连接归入池中。在池中保留一段生命期,它会自己释放连接。如果有的客户端连接中途突然断掉(如客户端重启了),它在侦听后无回应,它也会自己整理自己的连接的。我们在SQLSERVER线程中看到的连接,就是Open Data Services创建的。
Open Data Services有了连接(可能是创建的可能是从池里拿出来的,池化、创建、销毁都是非常讲究技能的。池化多少,上下文资源如何保留,池化多长时间,什么时候该销毁,调度不当就会严重消耗资源),就把SQL接住。这时,是接到了Open Data Services的读缓冲区里面。这个缓冲区为高性能处理数据的SQLSERVER带来一丝喘息机会,而就这一丝喘息机会,让SQLSERVER可以游刃有余(你的设计有吗?)。而Open Data Services有一个写缓冲区。SQLSERVER把检索到的数据,检索出来就立即放进写缓冲区,写缓冲区一满就立即被Open Data Service发走。当我过去研究SQLSERVER原理的时候,我常常赞叹,一个小小的SQLSERVER外围模块都设计如此精妙,实在让人佩服。我们经常在追求海量数据存储和Cache架构,我们却无视我们手边的SQLSERVER。
SQL语句放到读缓冲区,SQLSERVER的关系引擎就开始工作了。它总是在侦听这个读缓冲区。
SQL语句遇到的关系引擎的第一个模块就是命令分析器。我们在SQL查询分析器中看到的查询分析结果就是它的输出杰作。它来构造查询树。首先是将你的SQL语句规范化(你想想你写的软件代码,输入数据来了什么都不管就直接处理,连输入数据校验都没有,怎能稳定),否则以后的步骤将不好操作,如果你的SQL语句有语法错误,这个查询树的构造就无法完成,于是中断。而要规范一个SQL语句,首先要从SQL语法库中抽取SQLSERVER现有支持的各种语法和函数。
上一篇: PHP兑现各种排序