服务器 频道

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

  准备目标数据库

  当我们将复制源映射到目标上时,目标通常是一张基表。但是在有些情况下可以用视图代替,空间数据复制正是这样的情况。如果使用的是目标视图,那么目标表和基于这张目标表的目标视图必须预先定义好,这样才能用 Replication Center 定义映射关系。过去,目标视图通常用于合并、联合或外联接的情况。现在,由于 DB2 UDB v8.1 中提供了 INSTEAD OF 触发器,使目标视图具备了全新的应用潜能。这种触发器可以在对视图发出 INSERT、UPDATE 或 DELETE 操作时引发不同的处理逻辑。因此,目标视图与这样的 INSTEAD OF 触发器相结合通常情况下能够在 Apply 进程处理过程中扩展数据传输的可能性。

  我们已经有了一张源视图,它执行从空间数据到外部数据格式的转换,也将这张视图注册为复制源,现在,我们可以在订阅成员中使用这张视图。空间数据转换成的 BLOB 并不受 DB2 Spatial Extender 的直接支持。而且 BLOB 并不是 ST_Geometry 值,因此不能在 Extender 所定义的各种不同的空间函数中作为输入参数。首先,我们必须执行逆向转换操作,将 BLOB 转换成几何图形类型。本节将一步步地解释如何设置目标数据库。

  概述

  由于空间数据的存在,我们必须对目标表做一些额外的处理。再次强调,复制工具不认识空间数据类型(或其他任何结构化类型),也不知道我们用已知二进制形式传输空间数据。我们必须实现一种机制,将二进制数据及时(即在 Apply 进程向目标表插入数据的时候)转换成相应的几何图形。

  有了 DB2 UD v8.1 及其后续版本中的 INSTEAD OF 触发器,我们可以实现一种非常简单的解决方案。我们先自己创建目标表,在其上定义视图,并为这张视图提供三个 INSTEAD OF 触发器,用于执行将外部数据格式转换成几何图形,并插入目标表中的工作。 图11更详细地解释了这个过程。请您注意,这个额外的过程使我们不能使用由复制工具生成的目标表。因此我们必须自己创建这些表。

  图 11. 在目标数据库上的处理过程

 

  创建基本表及视图

  第一步是创建基本表,并在基本表上创建视图与 INSTEAD OF 触发器。基本表和视图的定义很简单,可以从源数据库直接拷贝过来。但是我们不需要在目标表中增加更新指示器字段。 清单9重复了这些步骤。如果目标表在另一个数据库或另一个模式下的话,我们可以选择相同的表名与视图名。不过在本例中我用了一个前缀“TG_”,这样能更清楚地表明我引用的是哪一张表。

清单 9. 创建目标表,并在其上创建视图

CREATE TABLE tg_streets (
   id     INTEGER  NOT NULL  PRIMARY KEY,
   name   VARCHAR(200)  NOT NULL,
   track  db2gse.ST_LineString
)@
CREATE VIEW tg_streets_repl_view(id, name, wkb) AS
   SELECT t.id, t.name, db2gse.ST_AsBinary(t.track)
   FROM   stolze.tg_streets AS t@

  准备好表与视图之后,您可以创建三个 INSTEAD OF 触发器。一个触发器负责在把新的数据从数据源复制到目标表上时发生的 INSTERT 操作。第二个触发器处理 UPDATE,当数据同时存在于源表与目标表,而在源表上对其进行修改时,这个触发器就派上用场了。当在源表的记录上执行了 DELETE 操作时,第三个触发器负责从目标表中删除相应的数据。 清单10显示了在视图 TG_STREETS_REPL_VIEW 上定义的这三个视图。

清单 10. 在目标表的视图上定义 INSTEAD OF 触发器
 
CREATE TRIGGER tg_streets_repl_i INSTEAD OF
   INSERT ON tg_streets_repl_view
   REFERENCING NEW AS n
   FOR EACH ROW
   MODE DB2SQL
   INSERT
   INTO   tg_streets(id, name, track)
   VALUES ( n.id, n.name, db2gse.ST_LineString(n.wkb))@
CREATE TRIGGER tg_streets_repl_u INSTEAD OF
   UPDATE ON tg_streets_repl_view
   REFERENCING NEW AS n OLD AS o
   FOR EACH ROW
   MODE DB2SQL
   UPDATE tg_streets
   SET    ( id, name, track ) = ( n.id, n.name,
             db2gse.ST_LineString(n.wkb, 1) )
   WHERE  id = o.id@
CREATE TRIGGER tg_streets_repl_d INSTEAD OF
   DELETE ON tg_streets_repl_view
   REFERENCING OLD AS o
   FOR EACH ROW
   MODE DB2SQL
   DELETE
   FROM   tg_streets
   WHERE  id = o.id@

  现在,所有的设置都已经完成,您可以定义订阅集合(subscription set )及其成员了。

0
相关文章