服务器 频道

在DB2 UDB中复制空间数据(上篇)

  总览图

  复制组件 —— 包括 Capture、Apply、Monitor 以及 Replication Center 的管理接口 —— 在一般情况下的设置并不能支持结构化的类型,特别是空间数据类型。Capture 程序不能解释 DB2 日志记录中所保存的空间数据,因此,我们必须采取一组措施克服这一限制。DB2 及其复制工具中已经内置了一些功能,可用来实现这些措施。让我们从高层开始介绍。

  当我们复制空间数据的时候,要先将其转换成 LOB 数据,更确切地说,是转换成二进制大对象(BLOB)。采用这种方式之后,复制工具就可以对一种已经支持的数据类型进行处理了,而且也并不知道这些 BLOB 数据实际上是空间数据。我们可以利用视图来实现这样的转换。我们可以在复制中定义视图,这样 Apply 程序在向目标进行完全更新的过程中就可以从一张来自源表的视图中取出数据,对于差量数据的更新则从 CD 表的视图中取出数据。视图实现了对源数据的“逻辑”扩展与/或解释,因此,Apply 程序就可以在获取数据的过程中对数据进行转换或扩展。在这样一种空间数据复制的实现方法中,我们针对源表定义一张视图,令其以 BLOB 的形式将空间数据包含在内。图3展示了这种方法的架构。

  图 3. 用 BLOB 复制空间数据

 

  Apply 进程对来自源视图的数据进行查询。在这里,它看到的不是 Spatial 字段,而是 BLOB 字段,这个字段中存储的实际上正是由源表转换来的空间数据。另外几个字段 —— 关键字字段“k”和数据字段“dl” —— 的复制方法与常规的 DB2 复制相同,不需要进行特殊考虑。数据是通过 Apply 进程插入到目标视图中的,如图中的虚线所示,这个过程最终跨越了系统的边界。目标视图的定义与源视图相匹配,这意味着存储空间数据的数据类型依然是 BLOB。 除了目标视图之外,我们还定义了三个 INSTEAD OF 触发器,用于在 INSERT、UPDATE 或 DELETE 操作的过程中实现逆向转换。逆向转换的作用是根据 Apply 进程复制过来的二进制数据构造出空间数据。

  完全更新(即将源表中的全部数据复制到目标表上)的过程中使用的也是同一套逻辑。基本的原则与差量更新(即只复制上一次 Apply 周期以来发生变化的数据)相同。对于差量更新来说,我们必须考虑变化数据表及变化视图(CD 表和 CD 视图)。CD 表是通过 Capture 进程来维护的,这个进程负责扫描 DB2 日志,提取出数据变化信息。然后将这些数据变化信息收集到 CD 表中。CD 视图的作用与其他的视图类似,是 CD 表中数据的一种不同的表现形式。这些视图是从实际需要进行复制的视图中派生出来的。 图4展示了源数据库,包括 CD 表和 CD 视图的定义。

  图 4. 源表、源视图与 CD 表、CD 视图

 

  现在我们面临一种两难的境地。首先,Capture 进程不能理解空间数据类型,因此,它无法收集 CD 表中变化的数据。第二个问题的来由是上面谈到的那个将空间数据在源视图中转换为 LOB 数据的过程。但是只要您考虑到 DB2 和 DB2 复制的下列功能,上述问题将迎刃而解:

  • 复制部分字段

    从一张表复制数据并不要求将这张表中的所有数据都复制过去。复制的数据源可以是字段的子集,这样的话,我们可以完全忽略掉源数据表中的某些字段。这一特性可用于在注册源数据表的时候忽略掉存储空间数据的字段。因此,我们就不会因为 Capture 不支持空间数据类型而受到限制。
  • 复制 LOB

    Capture 程序永远也不会从 DB2 日志中捕获 LOB 数据所发生的变化。当某个 LOB 字段注册为需要复制时,创建 CD 表的时候就会包含一个“更新指示器”字段,Capture 进程负责在读取源表的 DB2 日志记录的同时维护这个字段。当某条日志记录指示出 LOB 字段进行过更新时,这个更新指示器字段就设置为“U”;否则设为 NULL。从 Apply 这方面看,当源表的某个订阅中包含 LOB 字段时,Apply 程序会在 CD 表中查找与之相匹配的更新指示器字段,来检测 LOB 字段是否曾经更新。CD 表中那个相匹配的更新指示器字段与源表中 LOB 字段具有相同的名字。如果 LOB 字段被更新,那么 Apply 程序就直接从源表中取得 LOB 数据,然后将这部分数据应用到目标表上。

  在这种实现方式中,由于要通过视图中的二进制数据类型访问空间数据,因此对于 CD 视图也需要构建相同的逻辑。然而,Capture 进程并不知晓空间字段要按照 LOB 字段来处理。这就要求我们伪造一个更新指示器字段。我们向源表中增加另一个字段,并定义两个触发器,仿照 Capture 进程维护 LOB 字段的更新指示器的方式来维护这个字段。然后用 DB2 Replication 注册这个附加的字段,这样,对该字段所作的任何修改都能够被捕获并保存在 CD 表中。CD 表及 CD 视图便都可以包含这个更新指示器。

  现在就要用到前面描述的功能了。如图 4 所示,更新指示器字段标记为“@”。我们通过编写触发器,实现当空间字段被修改时将更新指示器的值设置为“U”。更新指示器同时也是 CD 表的一部分。这样,CD 表就可以保存空间字段是否被修改的信息了。CD 视图定义为将 CD 表中除更新指示器外的全部字段原封不动地映射过来,而将更新指示器的名字修改为经过转换的空间字段。结果是,Apply 进程在源视图中找到一个 BLOB 字段,又在 CD 视图中找到一个与该 BLOB 字段的名字相匹配的更新指示器字段。非空间性的数据是从 CD 表中取出的。当进行 INSERT 操作或 UPDATE 操作时,空间数据是从源视图中的 BLOB 字段里得到的,同时,CD 表中的更新指示器设置为“U”,表示空间数据曾经被修改过。 图5说明了上面所讨论的全部逻辑流程。

  图 5. 空间数据复制概览

 

  

  下面几节将更详细地解释把空间数据转换成 BLOB 的必要性,以及如何设置源表和目标表。随后我们还会给出一个例子,引导您在 Replication Center 中执行各种必要的操作,并帮助您完整地理解这种空间数据复制方法。

  结构化类型的转换函数

  现在,让我们来看一看空间数据是如何在数据库服务器和客户机之间传送的。空间数据的表现形式为结构化的数据类型。正如在其他任何一种编程语言一样,结构化数据无法实现原封不动的简单传送。我们需要对其进行线性化处理,或将其转换成某种形式的字节流。然后,再把这种字节流从客户机传送到服务器上,反之亦然。

  DB2(以及 SQL 标准)使用所谓的“转换函数”(transform function)来执行线性化操作,将 DB2 内置的结构化数据转换成外部表现形式,也可以转换回来。这种外部表现形式是一种单一的基于内置数据类型的标量值。内置数据类型可以是 VARCHAR、INTEGER、BLOB 或 CLOB,或者是 DB2 中包含的任何其他数据类型。转换结果到底要求为何种数据类型,这取决于特定的转换过程。在 DB2 Spatial Extender 中,我们用 BLOB 代表空间数据的外部二进制表现形式,而用 CLOB 代表空间数据的外部文本表现形式。

  为了在 DB2 客户机和服务器之间实现通信过程,我们需要两个不同的转换函数。一个函数用来将空间数据从 SQL 形式转换成外部数据格式,另一个函数则将外部数据格式转换成 SQL 形式。为了简化这两个转换函数的使用过程,您可以采用“转换组”(transform group)。转换组中包含一个 FROM SQL 函数和一个 TO SQL 函数,前者负责将结构化数据转换成外部格式,后者负责根据用外部格式表示的数据构造出 SQL 数据库中的结构化数值。

0
相关文章