RDS是关系型数据库服务,是一种即开即用、稳定可靠、可弹性伸缩的在线数据库服务。具有多重安全防护措施和完善的性能监控体系,并提供专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。
RDS 是关系型数据库服务(Relational Database Service)的简称,是一种即开即用、稳定可靠、可弹性伸缩的在线数据库服务。具有多重安全防护措施和完善的性能监控体系,并提供专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。
关系型数据库
关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织。 当前主流的关系型数据库有 Oracle、DB2、PostgreSQL、Microsoft SQL Server、Microsoft Access、MySQL 等。
云关系型数据库(RDS)是一种稳定可靠、可弹性伸缩的在线数据库服务,支持 MySQL、SQL Server、PostgreSQL、PPAS(Postgre Plus Advanced Server,高度兼容 Oracle 数据库)、MariaDB 等引擎,并且提供了容灾、备份、恢复、监控、迁移等方面的全套解决方案。
远程数据服务
RDS(Remote Data Services,远程数据服务)是允许我们处理客户端数据的一系列服务的统称。不用担心这方面的问题,因为 RDS 本身就是 ADO 的一部分,只有在需要传送和使用客户端数据时,才会使用。远程数据服务 RDS 允许程序员开发原生的 WINDOWS 分布式多层应用系统,或是开发以浏览器为图形用户接口的 WEB 应用系统。
远程数据服务 RDS 提供了客户端应用程序在 INTERNET/INTRANET 或分布式环境中使用 ADO 中 RECORDSET 对象的能力。
可以在浏览器中通过远程数据服务 RDS 取得 RECORDSET 对象,然后在脚本语言中存取数据。或在原生 WINDOWS 应用程序中通过 RDS 取得 RECORDSET 对象,然后使用程序代码来存取远程数据源中的数据。RDS 能够将 ADO 取得的数据一 DCOM 或 HTTP 通信协议由中介软件或中介组件传递给客户端,并且把数据缓存在客户端中让客户端存取数据。
与 ADO
程序<–>ADO<–>RDS<—->IIS/PWS<–>ODBC<–>数据库.
当我们在程序中试图使用 ADO 来存取 WEB 数据库时,由于 ADO 与 ODBC 分属于两台通过 Internet 连接起来的机器上,因此数据存取方式与 ADO,ODBC 同属于一台机器的情况大不相同,为了让程序也一样可以利用 ADO 存取 WEB 数据库,于是诞生了 RDS,而 RDS 的角色就象是一位帮 ADO 存取 WEB 数据库的服务员一样,所以取名“远程端数据服务”实际上 RDS 是由几个组件构成的。图 10-1 说明了这些组件以及它们之间是如何协同工作的。
组件似乎很多,但并不是所有的组件在每种情形下都被使用,实际上有一些不是 RDS 的一部分。然而这里还是把所有可能出现的组件都放在了图上,以备需要时查看。图 10-1 分成了两部分,因为使用客户端数据需要一些向客户端传送数据的方法,同时数据一旦到达客户端,也需要一些管理数据的方法。我们先从服务器端开始。
服务器
虽然 RDS 用于传送和访问客户端数据,但其确实有一些基于服务器的组件。这是必需的,因为肯定需要某种方式将数据传送到客户端。因此有了一系列能访问数据并允许发送数据到客户端的服务器组件。我们把实际的数据传送称为调度(marshal)。服务器端组件图的最上端是数据存储,由 OLE DB 提供者访问。它并不是 RDS 的一部分,但这表示只要有相应的 OLE DB 提供者,就可以通过 RDS 在客户端使用任何数据。至于如何处理服务器上的数据,可以有两种选择:· 数据工厂(DataFactory)是缺省的用于访问数据存储的服务器端组件。它作为服务器端 RDS 组件的一部分安装在计算机上,除了能从数据存储中获取数据外,还为服务器处理发送到客户端以及从客户端发送来的数据。· 自定义组件只是一个普通的提供了数据传送方法的 COM 组件。当数据工厂不能提供所需的功能时,可以使用自定义组件。本章将介绍一个简单的组件例子,在本书的后面还有一个更复杂的例子。Web 服务器使用这两种组件作为客户和服务器数据的接口。
客户组件
在客户端先从底端的 DataSpace 对象开始,该对象作为客户端的一部分与数据工厂或自定义对象协同工作。DataSpace 对象是一个代理对象,负责与服务器进行通信,同时也是数据传输的通道(或者通常所说的调度)。DataSpace 对象是用客户端脚本语言或用 HTML 语言中的标记创建的 COM 对象。在本章后面会看到关于这方面的例子。DataSpace 对象上面是数据源对象(Data Source Object,DSO),负责存储客户端数据。一个数据源对象??数据。客户数据缓存只是一种管理客户端数据的客户光标服务。同时数据源对象又是一个 COM 对象,与 DataSpace 对象类似,也可以通过客户端脚本或使用 HTML 语言中的标记来创建。同样,在本章稍后也会介绍关于这方面的一些例子。数据源对象的上面是数据绑定管理器,任务是建立 HTML 控件与数据源对象的连接。这就是我们所知道的绑定,可以通过设置某些 HTML 控件的 DATASRC 和 DATAFLD 属性来实现。下面将对这些内容进行讨论,并示范如何在浏览器中方便地使用数据。
浏览器
要知道 RDS 是微软的技术,因此只能在微软的浏览器上工作。实际上,只有在 IE 4.0 或者更高版本的浏览器中才完全支持 RDS。当编写依赖于 RDS 的应用程序时,需要注意访问应用程序的客户的 RDS 版本可能与服务器端有所不同。举例来说,IE 4 中的是 RDS 1.5 版本,而 IE 5、Office 2000 和 Visual Studio 6 中的则是 RDS 2.0 版本。有两种方法可以处理这种兼容性问题:
· 确保所有用户已经升级到 RDS 的最新版本。如果客户运行的是 Windows 2000,那么已经在运行最新版本的 RDS 了。RDS 2.5 版本是最新的随同 Windows 2000 一起发布的版本,同时也是一个可单独下载的软件包。· 当连接到数据源时,指定数据工厂的模式。这可以指定使用的是哪一个版本的 RDS 组件,后面将介绍这方面的一个例子。
数据源
数据源对象是一个存储和管理客户端数据的客户端对象。因为这是使用 RDS 最简单的一种方式,首先研究一下这些对象。
这里有几个不同的数据源对象,每一个都针对不同类型的数据:· 表格数据控件(Tabular Data Control,TDC),用于处理表格形式或分隔形式的文本文件。· RDS 数据控件,用于连接 OLE DB 数据存储,能够指定连接到哪个数据存储,以及返回哪些数据。· Java 数据库连接器,这是一个通过 Java 数据库控件(Java DataBase Control,JDBC)连接到数据存储的 Java 小程序。这里我们不想讨论 JDBC,因为它并不提供其他控件无法实现的功能。· 微软的 HTML(MSHTML)数据源对象用 HTML 标记数据,并把它作为数据源。· XML 数据源对象使用 XML 数据,用于结构化的或任意结构的 XML。
选用哪一种数据源对象取决于你想做什么,以及数据从哪里来。如果需要向客户提供少量的数据,并且不允许用户修改数据,那么表格数据控件(TDC)可能会比较适合。这种数据源是一个文本文件,不需要任何数据库,因此编辑起来比较简单。对于从数据库中取出数据并且可能需要更新的情况,RDS 数据控件是最合适的。而对于许多新数据源,会发现此时需要使用 XML 数据控件。这实际依赖于所使用的 Web 应用程序的类型,以及用户所需的功能。
数据控件
我们将依次介绍这些数据控件,一旦了解了如何用它们把数据传送到客户端,将会介绍如何使用这些数据。
表格数据控件
表格数据控件(Tabular Data Control,TDC)是最简单的数据源对象,主要用于少量的只读数据,特别是那些从不改变或很少修改的,不需要从客户端进行更新的静态数据。例如,表格数据控件能提供一个网页内的菜单项或链接的列表。
通过在 HTML 代码中使用标记可以创建一个表格数据控件。参数 DataURL 可以指定包含文本数据的文件名。
TDC 只读取表格中的数据或标记为表格形式的数据,例如,可以处理逗号分隔形式的数据(Comma Separated Value, CSV),类似于下面的数据:”172-32-1176″,”White”,”Bob”,”408 496-7223″”219-46-8915″,”Green”,”Marjorie”,”415 986-7020″”238-95-7766″,”Carson”,”Cheryl”,”415 548-7723″”267-41-2394″,”O’Leary”,”Michael”,”408 286-2428″”274-80-9391″,”Straight”,”Dean”,”415 834-2919″”341-22-1782″,”Smith”,”Meander”,”913 843-0462″”409-56-7008″,”Bennet”,”Abraham”,”415 658-9932″TDC 也可以自由定义。除??记的参数项或编写脚本代码来配置这些参数。参数的说明如表 10-1 所示:
下面是使用参数创建 TDC 的一个例子。也可以在客户端脚本中获取数据,下面的例子显示了给 TDC 加载数据的 JScript 脚本。function fillTDC(){ dsoAuthors.dataURL = ‘authors.csv’; dsoAuthors.Reset();}如果改变了 TDC 的 DataURL 参数,必须使用 Reset 方法,这样才能使新的 URL 起作用。当介绍数据绑定时,会更详细地讨论如何使用它。Reset 方法是 TDC 唯一的一个方法。 2. RDS 数据控件 RDS 数据控件能够访问一般的数据存储,而不是平面文件。它通常用于连接 SQL 数据库以从表、查询或存储过程获取数据。与 TDC 不同,RDS 数据控件允许更新数据。在本章稍后通过示例说明如何进行数据更新。类似于 TDC,可以用 HTML 脚本中的 OBJECT 标记来创建一个 RDS 数据控件,并以类似的方式设置其属性。authorsonclick=”resetData(‘publishers’)”>publishers 下面创建虚表。 这充当了模板的作用。注意,表格中还没有单元格。这是因为并不知道数据有多少个字段,所以也将在运行期间创建它们。编写 JScript 代码。首先看一下 resetData 函数,该函数设置数据控件的属性并加载数据。function resetData(sTable){ // reset the data dsoData.Connect = ‘Provider=SQLOLEDB; Data Source=’ + ” + ‘; Initial Catalog=pubs; User ID=sa; Password=’; dsoData.Server = ‘http://’; dsoData.SQL = ‘SELECT * FROM ‘ + sTable; dsoData.Refresh();} 虽然这看起来比使用参数更复杂一些,但是仍然比较简单。别忘了参数名是如何映射到属性的?这里所做的就是设置那些属性,然后调用 Refresh 方法更新数据控件。看上去,这可能比以前的例子更糟糕,因为在代码中只有不多的 ASP,也只是简单地在属性中填入 Web 服务器的名字。但使用该方法可以在不修改代码的情况下将此 ASP 页面从一个服务器移到另一个服务器。作为数据源的表名可以通过选择适当的按钮而传给函数。一旦加载了数据,将触发数据控件的 ondatasetcomplete 事件,运行 createCells 函数。function createCells(){ var fldF; var tblCell; // delete what’s there already deleteCells(); // now create the new cells for (fldF = new Enumerator(dsoData.recordset.Fields); !fldF.atEnd(); fldF.moveNext()) { // create a new cell for the heading tblCell = tblData.rows【0】.insertCell(); tblCell.innerHTML = ” + fldF.item().name + ”; // create a new cell for the body tblCell = tblData.rows【1】.insertCell(); tblCell.innerHTML = ‘ fldF.item().name + ‘”>’; } // now bind to the data source tblData.dataSrc = ‘#dsoData’;}这同样也很简单。首先删除了现有的表格单元格(马上会介绍这个函数),然后遍历记录集的字段。在行头为每个字段创建一个新单元格(这个表格只有两行:第一行,即第 0 行,是表头;第二行,即第 1 行,是表体)。表格单元创建完后,将 innerHTML 属性设为对应的字段名。在表体中创建新单元格的过程类似,但此时使用 innerHTML 元件保存绑定到数据字段的 INPUT 标记。当所有的字段都完成这样的操作后,这个表就与数据控件绑定了。因为这个页面允许在两个不同的数据集之间进行切换,所以需要先删除现有的数据。function deleteCells(){ var iCell; var iCells; // unbind the table tblData.dataSrc = ”; // delete existing cells iCells = tblData.rows【0】.cells.length for (iCell = 0; iCell < iCells; ++iCell) { tblData.rows【0】.deleteCell(); tblData.rows【1】.deleteCell(); }}这个子程序只是对表解除绑定,然后在表格中遍历所有的单元格并删除它们。等到上述程序执行完毕,表格就只剩下空的表头和表体行。这是一个用 RDS 和一些 DHTML 实现的简单例子。可以容易地把其加到一个 ASP 包含文件中,并把该文件放到任何应用程序中,即使数据源不改变也可使用这种方法。这个例子的全部代码——文件 RDSDynamicBinding.asp 以及类似的其他类型的数据控件例子,可以在 Wrox 站点上找到。 10.2.6 更新数据迄今为止,仅学习了在客户端如何取到数据,但还没有涉及如何更新客户端数据,和将其送回服务器。别忘了,记录集是断开连接的,那么如何更新数据呢?对数据所做的任何修改只是数据控件中本地记录的一部分,因此为了更新服务器必须发一条特殊的指令。然而这并不需做什么复杂的工作,因为 RDS 数据控件有两个方法,允许我们要么取消最近对数据所做的任何修改,要么将所有修改送到服务器。为了方便用户,可以为此创建一些按钮。 ONCLICK=”dsoData.CnacelUpdate()”>Cnacel ONCLICK=”dsoData.SubmitChanges()”>SaveSubmitChanges 方法只将那些改动过的记录送回服务器,而 CancelUpdate 方法则取消在本地记录集上所做的任何修改。更新和取消更新操作并不是唯一所需的。如果想增加新的记录或删除一条现有的记录,怎么办?可以使用记录集的 AddNew 和 Delete 方法。这将增加或删除记录集中的记录,然后在发送 SubmitChanges 命令后,服务器上的数据就可以被更新。 ONCLICK=”dsoData.recordset.Delete()”>Delete ONCLICK=”dsoData.recordset.AddNew()”>Add 1. 解决冲突的方法 由于与数据源断开连接,可能会碰到有关冲突的问题。例如在更新一条记录并将其保存到数据存储的时候,有人也修改了这条记录时,会发生什么情况? SubmitChanges 方法已经提供了相应的处理冲突的方法,如果发生冲突,那么该方法将产生一个错误。 在调用 SubmitChanges 方法期间,只要其中一条记录更新失败,那么所有的记录更新都会失败。这保证了原始数据不会被部分更新。可以遍历记录集,并检测记录的 Status 属性来告诉用户哪一条记录更新失败了。例如,最好调用自己的 updateData 函数,而不只是在命令按钮中调用 SubmitChanges 方法。 此时,我们知道已经发生了一个错误,但并不知道是哪一个错误,因此必须重新同步当前数据与数据存储中的数据。使用 adResyncUnderlyingValues 确保只有字段的 UnderlyingValues 属性被数据存储中的值覆盖,也就是说所做的修改是安全的(记住,修改的内容保存在 Value 属性中)。可以在后面的代码中比较当前的值与数据库中的值。 Status 可以是不同值的组合,详见附录。例子代码( RDSConflicts.asp )中有一个将这些值转换为描述性字符串的函数。 我们知道记录有某些形式的冲突,但无法确切地知道为什么或哪一个字段引起了冲突。因此需要遍历字段检测它们的值。 这就是 UnderlyingVaule 属性发挥作用的地方。 字段有三种值: Vaule 代表新值,即经过修改的字段值。 UnderlyingVaule 代表数据存储中存储的字段值。 OriginalVaule 代表从数据存储读取后,但还没有修改之前的字段值。 这意味着 UnderlyingVaule 会保存其他用户修改过的值,而 OriginalValue 是字段原有的值。因此比较两者之值,如果不同,则说明字段已经被另外的用户修改了。 可以利用所有这些错误信息来创建一个表格以显示是否确实发生错误。例子(RDSConflicts.asp)产生的输出结果如图 1 0 – 11 所示。 这里可以见到三种不同的值。原始值是 Johnson。然后,在另一个窗口(如 SQL Server Query Analyzer)中将值改为 Johnson。在浏览器窗口,利用 RDS 将这个值改为 Andy,并按下 Save All Changes 按钮。Resync 命令将数据库中的值取出并写入 UnderlyingVaule 属性。我也对 Lastname 列做了相似的修改。 使用这种方法,可以看到每一个发生变化的字段的值。由于 SubmitChanges 方法可以处理多个字段,读者可能希望为这个表增加额外的列以显示 ID 字段,这样就可以看到是哪一个字段更新失败了。