深度对比Oracle与SQL Server(一)

一般的公司通常会在他们的信息系统架构中引入多种数据库平台,同时引入三到四种不同的RDBMS解决方案的中大型公司也并不少见,当然这些公司里面的DBA们通常也需要同时拥有管理多种不同平台的技能了。

只在一种平台上展开工作的数据库专家们也通常会期待着在他们的下一份工作中能学到点不一样的东西,那些有勇气的人们则愿意花时间、金钱和精力去学习新的东西,也有其他因为换了新公司或者是为了找新的工作而去学习新的系统的人们,毋庸置疑的一点就是公司老板和人力专家们会更加青睐于那些拥有多个领域经验的求职者。

依我个人的经验来看,在学习一个新的数据平台的时候,最好的方法就是在新的环境中去发现那些你已知的东西,这样学习起来会简单很多。当然,当中也会遇到一些全新的概念需要去学习,或者是忘掉一些你现在已知的概念,但不管怎么说你不是从零开始的。比如说一个做SQL Server开发人员在要写Oracle存储过程的时候可能会先去找那些内置的函数然后比较它们之间不同点,她也可能会去比较变量声明以及错误处理的异同。

本系列文章中我将尝试对Microsoft SQL Server和Oracle RDBMS(以10g及以后的版本为主)进行一个深入的比较。我会主要集中于这两种数据库之间架构上的比较,当然不要期望我会给你一个详尽的比较清单,但是我会尽我所能的让你看清这两种当今世上应用最广的数据库之间的相同和相异之处。本文是以一个SQL Server DBA的角度去构思和写作的,不过相信这对Oracle专家门了解SQL Server这一面也是很有参考价值的。

废话少说,开工吧。

top操作系统的支持

Microsoft SQL Server向来都从属于Windows大家族中的一员,要让Microsoft发布一个支持其它操作系统版本的可能性当然是小之又小的了。当前来说 SQL Server可以在XP、Vista、Windows Server 2000、2003、2008上运行,同时也有针对于32位和64位版本Windows的数据库版本。

对Oracle来说,它支持多种不同的操作系统平台,包括Windows(32位和64位),另外还有支持Linux和不同分支的 Unix(Solaris、HP-UX、AIX等等)

top版本和发行版

在本写作时,Microsoft数据库产品的最新版本是SQL Server 2008,即将推出的下一版本是SQL Server 2008 R2,现在已经在CTP阶段了,它的上一个版本,SQL Server 2005,相对于再之前的SQL Server 2000的一个大升级。不过对很多公司来说SQL Server 2005还是有点新,因为他们现在还是在大量的使用着SQL Server 2000.

另一方面Oracle一路走来最新版本已经到了11gR2了,现在主流应用的版本10gR2已经发行有一段时间,已经是公认的领头羊了。 Oracle在10g中第一次提出“网格计算”的概念。当然现在还有公司依然在依赖于Oracle 9i处理业务。

说到发行版,SQL Server 2008 R2现在提供下面这么些版本:

企业版

企业版包含所有的高级特性,适用于大规模、高容量的数据库需求。

标准版

标准版为那些不需要包含企业版高级特性的公司提供了一个相对便宜的数据库平台,大部分公司使用的都是标准版的数据库。

工作组版

工作组版适用于小的部门级别的应用。

Web版

这个适用于作为Web应用的低成本的后台解决方案。

Express版

这是一个很小的内嵌式的SQL Server引擎,通常用于本地数据存储或是小规模的系统开发。Express版可以免费下载并且自由分发。

Compact版

Compact版可以让用户开发Windows桌面或者是手持设备的应用。

开发版

所有企业版所拥有的功能开发版都有,不过它仅仅授权单个用户访问,主要用于开发或是测试目的。

除了企业版,SQL Server 2008 R2还为数据中心和数据仓库提供两个“白金版”,这两个版本分别称为数据中心版 (Datacenter Edition)和并行数据仓库版(Parallel Data Warehouse Edition)。

对于Oracle 11g R2,发行版是这么样的:

企业版

这个版本提供了顶级的性能,同时价钱也是顶级的。像SQL Server的企业版一样,所有这个产品能提供的特性在这个版本里面都有。

标准版

这个和SQL Server标准版很像,Oracle标准版包含了大部分业务应用所需要的大部分特性。

标准版1

这个版本为小型工作组应用而设计,授权最小的用户为5。

Express版

这个目标客户是小规模应用或者是数据库开发入门,可以免费分发。现在Express版还处于10g R2版本。

下表提供了SQL Server和Oracle数据库发行版的直观的对比:

SQL Server Oracle
Enterprise Edition Enterprise Edition
Standard Edition Standard Edition
Workgroup Edition Standard Edition One
Express edition Express Edition
Web Edition
Compact Edition X
Developer Edition Enterprise Edition

top实例、数据库和表空间

SQL Server和Oracle之间第一个架构级别的差异就在于对实例 (instance)和数据库(database)概念的定义了。

SQL Server中,实例一词用来代表一个包含了操作系统文件、内存结构、后台进程以及注册表信息的独立的应用服务。在Windows系统中用一个存在着停止和运行状态的服务来代表一个实例,当处于运行状态时,实例要占用一定的服务器内存以及生成一定数量的后台进程。

SQL Server实例的中心是数据库。一个SQL Server数据库指的是一个资料库以及操作数据所需要的程序代码,当实例没有运行时,实例中的数据库就不能够访问。

SQL Server有两种数据库:系统数据库(system databases)和用户数据库(user databases)。在一个SQL Server实例安装完成之后,将会自动创建5个系统数据库:master, model, msdb, tempdb和resource。如果一个机器上面安装了多个SQL Server实例时,没有实例都会有自己单独的一套系统数据库。除了msdb数据库之外,其它数据库不能访问或是被损坏都会导致实例无法启动。相比之下用户数据库由DBA或者是开发人员在数据库实例安装完毕、系统数据库都启动之后所创建的,这些数据库中保存着公司的业务资料。

简而言之,一个SQL Server实例总是要包含一些数据库(尽管有时只是那些系统数据库),一个数据库也总是要有一个(且仅有一个)与之关联的实例。

从物理角度说,一个SQL Server数据库表现为存储于磁盘上面的一组操作系统文件的集合。数据库文件分为两种:数据文件 (data file)和事务日志文件(transaction log file)。一个数据库至少要包含一个数据文件和一个事务日志文件,SQL Server数据库的资料主要是存在于数据文件中,事务日志文件用来记录发生在这些数据上面的变更记录,SQL Server在执行系统恢复的时候要用到它。一个数据文件或事务日志文件只能隶属于一个特定的数据库,不存在两个数据库共用一个数据文件或者是日志文件的情况。一个数据量很大的数据库可以使用多个数据文件,这些数据文件能够被逻辑的组合成一个称为文件组(file group)的逻辑组。

在Oracle中,这一切看起来都有点反着来了。当Oracle启动时,它和SQL Server一样要先占用一些服务器内存用于执行操作,这个内存区域——著名的SGA(System Global Area)—— 被分为数个不同的结构,在创建SGA的同时也会启动一系列的后台进程用于和SGA进行交互,在这里这些分配的内存空间和后台进程组合起来就是Oracle实例了。请注意现在我们没有见到数据库的影子还,实际上 Oracle实例在没有数据库或是数据库不能访问时也是跑的很好的,在安装Oracle时,我们可以选择只安装软件,完了之后再安装数据库。

Oracle中的数据包含了一组操作系统文件。不像SQL Server数据库,Oracle数据库并不能代表数据库对象的逻辑分组,它更像是表示包含多个存在于磁盘上的用来保存数据的文件的一个单个的集合名词。

组成Oracle数据库的文件可以分成三个类型:数据文件(data file)、重做日志文件(redo log file)和控制文件(control file)。数据文件保存数据,Oracle中可以存在任意数量的数据文件;重做日志文件跟SQL Server的事务日志文件一样用来保存对数据更改的记录,在系统恢复阶段需要用到;控制文件是一些特别的小文件,用来保存一些至关重要的关于数据库的信息,没有这个文件的话,实例就无法打开数据库。

除了数据文件、重做日志文件、控制文件之外,数据库还包含参数文件(parameter file)、密码文件(password file)和可选的归档日志文件(archive log files),后面很快会对这些文件类型展开讨论。

Oracle系统启动时,首先在内存中创建数据库实例,然后由实例找到保存在磁盘中的数据库,最后打开数据库让用户操作。当系统关闭时,实例会从内存中清除掉:整个内存结构和后台进程都会消失,但是数据库依然存在于磁盘上,只是处于关闭的状态。之前也说过,Oracle实例可以在不打开数据库的情况下运行——这是与SQL Server数据库最大的不同,SQL Server实例是不能够离开系统数据库而运行的。不过和SQL Server一样Oracle数据库在实例没有启动的情况下也是不能访问的。

一般来说Oracle实例和数据库之间是一对一的关系。一个实例对应着一个数据库,但是一个数据库却可以同时由多个实例去访问它。一个独立的 Oracle安装包含一个实例和一个供实例操作的数据库,而配置成RAC(Real Application Cluster)的安装则可以允许多个存在于不同机器上的实例访问存在于一个共享磁盘上面的数据库。

那Oracle中数据库对象的逻辑分组在那儿呢?在SQL Server中逻辑分组由数据库自己来完成,而在Oracle中,这项工作由表空间(tablespace)完成,Oracle表空间是用来对表、视图、索引和其他数据库对象进行分组的逻辑结构。例如,你的 Oracle产品库可以给HR应用一个单独的表空间,支付应用则使用另外一个。一个数据库可以逻辑的分成若干个表空间,这些表空间在物理上则由一个或者多个数据文件组成。因此在Oracle中与SQL Server数据库等价的是表空间。

由于这两种结构在功能上相当类似,在SQL Server中建立数据库的过程和在Oracle中建立表空间的过程也非常相似。不管是建立数据库还是表空间,DBA都要首先指定一个名字,然后给新建的数据库或者表空间分配一个或多个数据文件,并为每个数据文件指定初始大小和数据增长情况。

在SQL Server中可以做到让一个用户数据库离线或是只读,Oracle的用户表空间也一样可以。在SQL Server中可以让一个用户数据库中的一个或者多个数据文件只读,而Oracle用户表空间中的一个或者多个数据文件也同样能标记为离线。

不过数据库和表空间在某些方面还是有差别的:

* SQL Server中,数据文件可以用文件组逻辑的进行分组,而Oracle表空间就没有类似的概念。

* SQL Server的每个数据库都有自己的事务日志文件,而且在创建数据库的时候就要指定这些日志文件的属性。而在Oracle中整个数据库(意为所有的表空间)的事务日志都是记录在同样的一样重做日志中,因此也不存在说给每个表空间建立一个单独的日志文件的说法。

* SQL Server中,数据库可以设置成简单恢复模式(simple recovery mode),简单恢复模式指的是活动的数据库日志在checkpoint操作完成之后就会截断。Oracle也有类似的概念,这个稍后会说到,不过不能在表空间级别上进行这样的设置。

top实例名和SID

SQL Server和Oracle都允许在同一个机器上面同时运行多个实例,多个实例的执行环境是完全独立的:就单个的数据库引擎而言,它并不知道也不关心有没有其他的实例在这个机器上运行着。

在SQL Server中这种机制通过实例这个概念来实现,SQL Server可以作为一个命名的(named) 或是 默认(default) 的实例来运行,默认实例的名字和运行它的Windows服务器的名字一样,显然一个系统的默认实例只可能存在一个,不过在一个机器上可以存在多个命名的实例,命令实例的名字格式为 HOSTNAMEINSTANCE_NAME ,同一个主机上每个运行实例的 INSTANCE_NAME 必须是唯一的,每个实例都有着自己的一套程序文件以及一些与其它实例共享的通用组件。

而Oracle也差不多,在安装Oracle的时候,DBA就需要指定一个 全局数据库名(Global Database Name)和系统标识符 (SID, System Identifier)。Oracle中实例和数据库是完全不同的东西,一个全局数据库名用来在网络上唯一的识别一个数据库的存放位置,一个完整的名字通常是下面的格式database_name.network_domain_name。 SID则是用来识别一个与数据库关联的实例,大都数情况下一个实例关联一个单个的数据库,数据库名和SID名字会是一样。RAC环境中就不一样了,RAC 允许多个实例访问放在共享存储中的同一个数据库,此时的实例名和数据库名字将不一样。当然和SQL Server一样,一个Oracle数据库服务器上面是不允许两个实例使用同一个SID的,另外一点类似的就是在安装时一旦指定,不管是SQL Server实例名还是Oracle SID都是不能再修改了。

SQL Server DBA可以通过下面的语句查询当前登录系统的实例名:
查看源代码
打印帮助
1 SELECT @@SERVERNAME

Oracle DBA用来查询实例名和数据名的语句如下:
查看源代码
打印帮助
1 SELECT INSTANCE_NAME, HOST_NAME, VERSION, DATABASE_STATUS FROM V$INSTANCE;
2 SELECT NAME, DATABASE_ROLE, CREATED FROM V$DATABASE;

top系统数据库和系统表空间

一个SQL Server实例需要有5个系统数据库(2005之前的是4个):master, model, msdb, tempdb和resource,一个Oracle数据库则最少需要3个系统表空间才能正常操作,它们是:SYSTEM, SYSAUX和TEMP。

master和resource数据库集中保存了SQL Server自身管理所需要的所有信息,里面保存了诸如系统配置,数据库列表和文件路径、终结点、连接服务器和用户帐户(或“登录”信息),系统级别的对象存储在只读的数据库”资源(resource)”中。

在Oracle中,SYSTEM表空间等价于master数据库,SYSTEM表空间包含了数据字典(data dictionary),也就是关于Oracle自身的元数据(metadata),这里的数据字典可以和SQL Server中的resource数据库进行类比。到这里你也许猜到了:如果SYSTEM不存在或是损坏了的话Oracle数据库是打不开的。

对于一个SQL Server实例,model数据库用作这个实例中所有新建的数据库的“模板”,对model数据库的任何修改都会反应到之后新建的其它数据库里面。在 Oracle中就没有这样的模板,不过在你新建一个表空间的时候,你可以指定这是一个永久的表空间或者是其他类似TEMP和UNDO一样的表空间,永久表空间才是用来保存用户数据的。

SQL Server的tempdb用作整个实例的“试验田”,每次实例重新启动的时候tempdb都会重新创建。Oracle的TEMP表空间的作用类似:用来包括大的排序操作的中间结果。当然SQL Server的tempdb还能用来保存行版本(row versioning)所需要的信息,当行版本启用后,行版本特性可以保证数据库引擎能将数据行的每次的修改记录保留下来,修改之前的行会保存在tempdb里面的版本库中,一般查询会返回一个数据行上最后提交的版本,当一个使用了特定隔离级别的依赖行版本的读操作不再会阻塞其它修改同样数据的事务,这是因为读操作不会在数据行上使用共享锁。不过这个特性需要在单个数据库上单独启用。

Oracle中使用一个单独的表空间——著名的UNDO表空间——来达成同样目的。UNDO表空间保存着被DML语句修改的数据块的读一致性的副本。当用户开始对数据进行修改的时候,修改之前的数据块会被保存到UNDO表空间中,当另外一个用户需要查询这些数据的时候,他取到的实际上是UNDO表空间中查出来的读一致性的版本。不像SQL Server的行版本,Oracle的UNDO不需要启用——因为它是属于Oracle并行访问机制的一部分。

最后一个要介绍的SQL Server中的msdb数据库,SQL Server代理服务需要操作这个库。SQL Server代理负责计划任务、警告、复制、日志传送以及其它的很多东西,代理服务的正常运行离不开msdb数据库。

在Oracle没有明确与mdsb数据对应的东西。SYSAUX表空间也是一个系统表空间,在安装过程中(译注:准确说应该为“数据库创建过程中”)创建,它里面保存了诸如Oracle AWR(Automatic Workload Repository)信息、多维数据和多媒体数据,XML数据库等等。