摘要本文介绍了在客户机上处理 Microsoft SQL Server 查询的方式各种客户机与 SQL Server 的交互方式以及 SQL Server 在处理客户机程序的请求时需要完成的工作
简介
Microsoft(R) SQL Server(TM) 内部机制和结构是一个非常大的主题因此本文仅限于程序开发人员感兴趣的问题集中研究其他源中没有彻底讨论的问题在讨论 SQL Server 的结构时我们主要观察客户机的处理过程研究不同的客户机程序与 SQL Server 的交互方式以及 SQL Server 如何处理客户机的请求还有一些讨论 SQL Server 其他方面的信息源特别是 Microsoft Press 出版的 Inside SQL Server 作者是 Ron Soukup 和 Kalen Delaney这本书非常详细地讨论了 SQL Server 存储引擎的内部机制和处理方法不过对查询处理器的讨论不够深入本文正填补了这个空白
我们期望本文有助于读者编写出更好的应用程序通过本文读者会在提高程序性能方面得到新的启发产生新的理解
SQL Server 是一种客户机/服务器系统
多年来SQL Server 一直被认为是一种客户机/服务器系统事实上Sybase DataServer(以此为基础开发了原始的 SQL Server)正是第一个作为客户机/服务器系统开发的商用关系数据库系统那这又说明了什么呢?这不只意味着 SQL Server 是一个双层系统从传统上看双层系统意味着客户机应用程序运行在一台机器上向另一台计算机上的服务器发送请求而对于 SQL Server客户机/服务器意味着 SQL Server 的组成部分即客户机 API 部分驻留在处理结构中的远端与服务器组件本身是分开的
在典型的双层模型中客户机程序部分驻留在台式机上具有大量客户机应用程序逻辑和业务逻辑并且会直接向数据库系统发出请求然后客户机得到服务器响应这些请求所返回的数据
三层系统也采用了同样的模型多年以来SQL Server 一直用在事务处理监视系统中例如 BEA 的 Tuxedo 以及 Compaq 的 ACMSxp这些系统早在二三十年前就采用了典型的三层模型三层模型在今天基于 Web 的应用系统中占据了支配地位这类系统以 Microsoft 的 MTS 以及新的 COM+ 为代表从 SQL Server 的角度看三层解决方案中的客户机程序是放在中间层的中间层直接与数据库交互实际的桌面或瘦客户机(Thin Client)使用其他机制并通常直接与中间层交互而不是直接与数据库系统交互图 描述了这种结构
图 三层系统模型
客户机结构
从结构的角度看SQL Server 关系服务器组件本身并不真正关心客户机程序运行的位置事实上就 SQL Server 而言即使在运行 SQL Server 的同一台机器上运行应用程序仍然还是客户机/服务器模型服务器运行一个单独的多线程进程为来自客户机的请求提供服务不管客户机的位置在哪里客户机程序代码本身是单独的运行在客户机应用程序内部的 DLL与 SQL Server 的实际接口是在客户机和服务器之间对话的表格数据流(Tabular Data Stream TDS) 协议
一个常见的问题是什么是 SQL Server 的本机接口呢?很长时间以来很多开发人员一直都不愿意使用 ODBC 这样的接口因为他们认为由 Sybase 开发的客户机 API也就是 DBLibrary是 SQL Server 的本机接口实际上SQL Server 关系服务器本身并没有本机 API它的接口就是在客户机和服务器之间的通信流协议 TDSTDS 把客户机发送给服务器的 SQL 语句封装起来也把服务器返回给客户机的处理结果封装起来任何直接处理 TDS 的 API 都是 SQL Server 的本机接口
让我们来看一下客户机的组件如图 所示客户机结构中的某些部分就不在这里讨论了因为它们不属于 SQL Server 的范畴但如果您在编写应用程序的话就必须了解这些部分大家知道得最多的应该是各种对象模型如果您正在编写 ASP 或 Microsoft Visual Basic(R) 应用程序就需要通过 ADO 与数据库系统交互而不是直接调用底层的 API例如 ODBC 或 OLEDBADO 映射到 OLEDB而 RDO 映射到 ODBC因此作为这种最常用的编程模型的对象模型并不是 SQL Server 客户机结构中的严格意义上的组件此外还有另外一些组件可以插接到 SQL Server 基础结构上面的这一层OLEDB 的会话池服务提供程序 (Session Pooling Service Provider)就是这种组件的一个例子
图 客户机结构
客户机接口
SQL Server 有两个接口可以认为是 SQL Server 的本机接口即 OLEDB 和 ODBCDBLibrary 接口也是本机的它与 TDS 通信但是 DBLibrary 使用的是 TDS 较老的版本需要在服务器上进行一些转换现有的 DBLibrary 应用程序仍然可以继续与 SQL Server 协同使用但是很多新的功能和性能提高等好处只能通过 ODBC 和 OLE DB 才能利用更新 DBLibrary 使其支持 SQL Server 的新能力将会导致与现有应用程序的很多不兼容性因此需要修改应用程序ODBC 在五年之前就替代了 DBLibrary是新的 SQL Server 应用程序更理想的 API因此引入不兼容的 DBLibrary 新版本并不明智
从图 可以看到所有这些客户机 API 都有三个部分最上面的部分实现 API 的细节例如行集和游标应该是什么样等等TDS 格式化程序负责处理实际请求例如 SQL 语句并将其封装成 TDS 消息包发送给 SQL Server获得返回的结果然后再把结果反馈到接口实现
还有一些供所有提供程序使用的公共库代码例如BCP 设备就是 ODBC 和 OLEDB 都可以调用的库DTC 也是这样第三个例子是 ODBC 规范的 SQL 语法即带有参数标记的 CALL 语法这些对于所有提供程序都是通用的
除了我们在前面已经提到的局限性即 DBLibrary 仍然只能使用 SQL Server 版TDS 协议对于所有 API 都是相同的ODBC 和 OLEDB 在与 SQL Server 通信时使用 SQL Server 版但也能够与 或 服务器通信另一个是 NetLibrary这是一个抽象层客户机和服务器都在此层上同网络抽象接口通信不必为 IPX 还是 TCP/IP 困扰在这里我们将不讨论 NetLibrary 的工作细节只要知道它们的工作基本上是将来自的网络通信底层的细节隐藏起来不让软件的其他部分看到就可以了