本文中对两种数据库平台的对比结果显示了在构建数据库应用程序时,使用SQL Server 2005(代码代号“Yukon”)结合Visual Studio进行开发比使用DB2 UDB 8.2(代码代号“Stinger”)结合Visual Studio有着显著的优势。在开发、调试和部署数据库解决方案的时候,这些优势就将转化为在时间和资金上的节省。在本文中特别说明了SQL Server 2005与DB2 UDB 8.2相比,对.NET数据库对象的支持要广泛的多。另外,你会发现在构建和管理数据库对象时,SQL Server 2005和Visual Studio集成的程度要比DB2 UDB 8.2和Visual Studio的集成紧密的多。在本文中,你还会看到SQL Server 2005所提供的开发平台除了关系型数据库之外,还有其他许多功能,这一点超过了DB2 UDB 8.2。
前言
在过去,IT开发技术分成了程序开发语言、产品环境配置和数据操作这三种相对独立的专业技能。为了综合使用这些相对独立的技能往往需要专门的技术和大量的人力。现在,有了SQL Server 2005和Visual Studio 2005,我们拥有了一个统一的开发环境,集成于其中的编程模型提供了整体的解决方案,包容了客户端数据库应用程序、服务器管理工具和服务器端数据库对象的构建。如此对工具和框架功能性的改善将使得开发者和客户都能从中受益,因为它将会对应用程序的可用性、性能、安全性和可伸缩性带来一个全面的提升。
SQL Server 2005和DB2 8.2中对Visual Studio环境和数据库数据提供程序的集成将简化和改善应用程序的开发流程。它们提供了旨在提高生产率的构建和部署应用程序的工具,这将会给程序开发和应用程序管理带来更好的性能表现。SQL Server 2005和DB2 UDB 8.2中对.NET框架的集成带来了一个更加高效和更加灵活的数据库应用程序开发环境,由此得到了比先前版本执行效率更高的更加健壮的数据库解决方案,它拥有更好的易用性和可伸缩性。通过利用集成的.NET环境,数据库开发人员就可以实现以前使用SQL代码不可能得到的结果。通过使用.NET框架,开发人员写出的代码能具有更加复杂的逻辑,更加适合于解决计算问题,并能访问到外部的系统和网络资源,因为.NET语言,例如Visual Basic、C#和C++,都是完全的面向对象编程语言,具有像封装、继承和多态性这样的面向对象编程的特性。它们还具有许多在SQL语言中不存在的功能,例如数组、结构化异常处理、集合等。
如今,Microsoft .NET提供了最先进、最高效的构建和整合数据库应用程序的环境。在这篇文章中,我们将比较SQL Server 2005和DB2 UDB 8.2分别提供的.NET集成的程度。为了能充分说明这其中的差别,我们将做一个详细的技术演示来显示分别使用SQL Server 2005和DB2 UDB 8.2构建一个.NET存储过程的具体步骤。
核心技术比较
虽然SQL Server 2005和DB2 UDB 8.2都集成了.NET框架和Visual Studio,但各自的集成程度有着显著的差别。下面这张表格中列出了关于它们对.NET的集成程度的比较。
|
数据提供程序
SQL Server 2005和DB2 UDB 8.2都自带了.NET数据提供程序,使得.NET客户端程序能够访问数据库平台。这些“天生的”数据提供程序与基于OLE DB的数据提供程序相比,会给服务器应用程序带来更好的性能和可伸缩性。这两种数据提供程序有着非常相似的功能,都能执行基本的ADO.NET对象,包括Connection、Command、DataReader、DataSet和DataAdapter。但它们有一个关键的差别:SQL Server .NET数据提供程序有两种模式可用,一个针对于客户端应用程序,另一个针对于服务器端应用程序。这一点对于服务器端应用程序开发特别重要,因为SQL Server服务器端.NET数据提供程序是一个驻于内存的程序,它不用像客户端数据提供程序那样去考虑网络流量的限制,因此,服务器端.NET数据提供程序能针对.NET数据库对象实现更好的性能。另外,服务器端数据提供程序还开放了一组只适合于服务器端代码的功能,例如服务器端游标。针对客户端应用程序的数据提供程序所开放的功能在System.Data.SqlClient命名空间中,而服务器端数据提供程序所开放的功能在System.Data.Sqlserver命名空间中。在DB2 UDB 8.2中,只有单独的IBM.Data.DB2命名空间。DB2 .NET数据提供程序使用DB2Context对象来创建驻于内存的数据库连接。
在服务器端,它们同样有相似之处。DB2和SQL Server都支持使用.NET语言构建应用程序以及随后在服务器端部署。其实除了这一基本概念,这两种数据库平台对.NET的集成程度有着很大的差异。DB2 UDB 8.2支持创建.NET存储过程和.NET用户定义函数。可是,Visual Studio IDE只支持创建DB2 UDB 8.2 .NET存储过程,DB2 UDB 8.2 .NET函数必须手工创建。与之相比,SQL Server 2005对.NET的支持要广泛的多。和DB2一样,SQL Server支持创建.NET存储过程和.NET用户定义函数。除此之外,SQL Server还支持.NET触发器、.NET用户定义类型(UDT)以及.NET用户定义聚集。所有这些对象的创建都被完全集成到Visual Studio 2005 IDE中了。能使用.NET语言构建存储过程和函数对数据库开发人员来说肯定是个好消息,这将使得他们能够实现更加复杂的商业逻辑和函数功能而不必受限于标准SQL的功能。这一点无疑是将.NET与数据库集成的关键所在,当然,使用.NET语言创建触发器、用户定义类型以及用户定义聚集也很有用。使用.NET语言创建触发器将使得触发器的代码能更加完全地封装商业逻辑,同时还能执行一些附加的操作,例如访问外部资源记录操作日志。使用.NET语言创建用户定义类型能使得数据库开发人员能扩展系统中原有的数据类型,这些用户定义类型能拥有自己独立的属性和操作符,这使得开发人员可以无缝地扩展原有的数据类型,在使用的时候就和原有的数据类型一样,具有各自的操作符和聚集。同样地,使用.NET创建用户定义聚集使开发人员能创建自定义的聚集操作应用于原有的数据类型或是用户自定义的数据类型。
除了这些基本的.NET功能,在.NET框架与各自的数据库服务器集成方面还有重大的差异。在下一部分中,我们将更深入地讨论.NET集成的细节。
.NET框架集成
Microsoft® .NET是用来把信息、人力、系统和设备联系在一起的一组Microsoft软件技术。.NET框架是构建和运行下一代软件应用程序和Web Service所必需的Windows组件。
.NET框架:
·支持超过二十种不同的编程语言。
·管理着大量的“管道”——有助于提高软件开发效率并使得开发人员的精力更加集中于核心商业逻辑代码上。
·使得构建、部署和管理一个安全的、健壮的以及性能卓越的应用程序比以前更加容易实现。
.NET框架由公共语言运行库(CLR)和统一分层的类库集合所组成。.NET CLR的职责主要包括集成语言的运行服务、强制安全性和对内存、进程以及线程的管理。在语言集成方面,CLR定义了通用类型系统(CTS),它描述了跨越所有.NET语言的基本数据类型以及关于那些数据类型的操作。.NET框架提供了大量的类集供开发人员应用于他们的应用程序中,这些类集涵盖了很多方面的内容,包括I/O、网络、文本处理、数据访问、加密、XML处理、Web Service等等。这样就允许开发人员能把精力主要集中在构建商业逻辑上而不是埋头于“管道”代码中,因为这些能在.NET框架的类集中找到。SQL Server 2005和IBM DB2 UDB 8.2中对.NET CLR的集成使得可以用任何一种.NET语言(包括C#、Visual Basic、C++以及J#)来开发数据库对象。
这两种不同的数据库平台和.NET框架集成的方式是完全不同的。SQL Server 2005数据库引擎将CLR宿于进程内,这意味着同时运行数据库引擎和.NET运行库只需要一个独立的操作系统进程。与之相比,DB2 UDB 8.2和.NET框架的集成采用的是“进程外”的模型。图1对不同的数据库CLR实现方式进行了直观描述。
集成模型的含意
SQL Server 2005集成.NET运行库时采用的“进程内”模型与“进程外”模型相比有一些非常明显的优势。首先,将CLR集成在进程内部使得SQL Server能以不同的方式控制CLR的运行。内存管理、垃圾收集器、线程支持的核心功能将受到SQL Server主机的控制,而不是采用.NET的默认设置和操作。这一点非常重要,因为SQL Server数据库引擎能更好地从整体的角度来考察系统需求,从而使得它能根据实际情况优化内存和线程的管理。最终,以“进程内”模型集成CLR的SQL Server 2005能创建得到更加健壮和有更好伸缩性的解决方案。
举个例子,考虑一个负担沉重的数据库实例,要响应许多并发的请求,这一情况已经持续了很长一段时间。SQL Server能自动和智能地在数据存储和程序逻辑(例如,.NET存储过程)之间平衡内存的分配。当系统的负担有了一些性质上的变化——例如,相对较多的请求利用了较多的程序逻辑——SQL Server会再次自动地进行调整。这样,系统的性能会根据满足实际需求的伸缩性和可靠性进行不断的优化。因为DB2 UDB v8.2采用“进程外”的模型集成.NET运行库,所以DB2不能提供这种类型的机器资源动态平衡和性能优化。
SQL Server 2005是通过使用CLR 主机API来实现动态优化的,这些API只在.NET框架2.0版中存在,而在.NET框架以前的版本里是没有的。必然的结果,SQL Server 2005需要集成.NET框架2.0版而DB2集成的是.NET框架1.1版,集成的程度自然较低。
.NET 2.0与.NET 1.1的差别
使用.NET框架2.0版结合SQL Server 2005和Visual Studio 2005与使用.NET框架1.1版结合DB2 UDB 8.2相比,有着一些显著的优势。.NET框架2.0版和以前版本相比,功能有着显著的增强:
·改善的性能和装载时间
·支持泛型(同一个类和方法可针对于不同数据类型的值一样运行,因此提高了代码重用性)
·支持“编辑后继续运行”(Edit-and-Continue),开发人员能够在执行过程中修改代码,而无需中止和重新开始调试会话。
·一个新的数据保护API(DPAPI),使得应用程序能对某些敏感信息加密,例如连接字符串甚至内存块。
·流的身份验证功能通过新的NegotiateStream和SslStream类允许您使用 Kerberos 或 SSL 来实现客户端和服务器端的安全通道。
·COM互操作性的改善将使得.NET应用程序在调用现存的COM对象时有着更好的性能和可靠性。
·经过改善的I/O性能加上对GZIP数据压缩的支持
·64位应用程序兼容性
部署.NET逻辑到SQL Server
每个数据库平台实际使用.NET对象的方式也是有着很大差别的。在SQL Server 2005中,一个新的SQL Server数据库对象程序集(Assembly)是部署.NET对象(例如触发器或是存储过程)的最小单元,程序集组是部署.NET逻辑的最小单元。为了创建CLR数据库对象,你必须首先使用Visual Studio 2005创建一个DLL。接着将这个DLL导入到SQL Server中作为一个数据库程序集对象。这些步骤能够使用命令行编译器和CREATE ASSEMBLY命令手工实现,或者像在技术演示部分里所看到的一样,Visual Studio 2005能自动完成整个流程。
SQL Server中Assembly的安全
SQL Server 2005给数据库管理员提供了一个新的安全单元——程序集。程序集可被标记为三种安全状态:SAFE、EXTERNAL和UNSAFE。这些安全标号供数据库管理员用来管理和保护所有在数据库里以程序集级别运行的.NET代码。SAFE标号表示这个程序集只使用托管代码并且不访问数据库之外的资源。EXTERNAL标号表示这个程序集使用托管代码访问外部资源,例如文件系统或是网络等非数据库之内的资源。UNSAFE标号表示这个程序集能够包含托管和(或)非托管代码,并且能够访问任何内部或外部的资源。由UNSAFE程序集创建的数据库对象只能被拥有系统管理员权利的用户执行。
部署.NET逻辑到DB2
虽然将.NET托管代码装入DB2 UDB 8.2的流程与装入SQL Server 2005的流程很相似,但在数据库对象类型和存储位置以及安全和数据库管理流程方面还是有着一些差别。为了创建DB2中的CLR数据库对象,你得首先使用Visual Studio并采用某种.NET托管语言创建一个DLL,这个DLL文件需要拷贝到DB2安装路径专门的目录中去,或者在创建存储过程或者函数的时候提供这个DLL文件的完全路径。这个DLL实际上不是一个数据库对象,也没有被导入到数据库表中,相反,它只是一个操作系统中的文件。接着,这个DLL将出现在创建数据库对象(例如存储过程或者函数)的CREATE命令中。在技术演示部分中,你将会看到使用Visual Studio 2003能够自动完成创建DB2 CLR存储过程的整个流程。不过,创建用户定义函数则不一样,你只用通过手工来完成创建用户定义函数的流程。
一个数据库管理员或者是一个应用程序开发人员通常需要保护与DB2外部程序相关的DLL程序集,这可以通过限制程序运行时的操作来实现,这步工作在创建过程或函数时,在CREATE语句的EXECUTION CONTROL子句中完成。有效的执行控制模式包括:SAFE、FILEREAD、FILEWRITE、NETWORK和UNSAFE。如果没有指定执行控制模式,默认模式是SAFE,这将意味着这个CLR程序只能访问由数据库管理员控制的资源,这样的资源包括所有的表和由数据库实例管理的架构。FILEREAD、FILEWRITE和NETWORK执行模式允许托管代码访问本地文件系统或者是网络上的资源。UNSAFE执行模式将不会在资源访问上做任何限制,标记为UNSAFE执行模式的程序可以执行二进制代码。既然DB2与.NET的集成采用的是“进程外”的模型,那么在使用CREATE语句创建DB2 CLR过程和函数时必须采用FENCED子句,用以说明.NET逻辑和数据库管理器在不同的进程中运行并且不使用共享内存通讯。这就造成了在程序逻辑与数据库本身之间传输数据的时候,与“进程内”模型相比,有一个性能上的障碍。