内容


借助 Informix Dynamic Server 中的外部表特性使用数据文件抽象

使用更简单的 SQL 界面的高性能 ETL

Comments

简介

Informix Dynamic Server (IDS) 11.50.xC6 支持创建表中数据位于数据库服务器外部的表,这些表称为外部表。这个外部表特性已在 Informix eXtended Parallel Server 中受到支持,XPS 客户经常使用该特性来加载和卸载他们的大规模数据集。现在,IDS 也支持这个特性,允许您轻松执行数据加载和卸载操作,从而获取最高的性能和最大的灵活性。

IDS 还提供一些数据加载和卸载工具,包括:dbimportdbexportdbaccess 命令(加载和卸载)、High Performance Loader (HPL) 和 dbload。这些工具用于将数据从一个 IDS 实例移动到另一个实例,并保存扁平文件格式的数据备份。总的来说,这些工具都是基于客户机的,因此,加载和卸载数据时需要通信成本(HPL 是个例外,因为它在服务器中有一个副本,用于完成这个工作)。

鉴于十年以来的数据增长,OLTP 服务器现在也在处理大规模数据,这就需要一个优化工具来执行提取、转换和加载(ETL)操作。IDS 服务器中引入的外部表满足了这个需求,并且改善了性能。

理解外部表概念

通常,通过 SQL 访问的数据完全由 IDS 存储和管理。通过可扩展性,IDS 还支持 Virtual Table Interface (VTI) 和 Virtual Index Interface (VII),后者支持用户以自己的格式无缝访问数据。

外部表对驻留在底层操作系统中的数据文件提供一个普通的表界面。这些文件可能采用某种 IDS 能够理解的形式(本文将在稍后讨论),以便可以通过 SQL 查询访问。

创建外部表

外部表可以采用以下三种方法创建:

  • 使用带有列指定的 CREATE EXTERNAL TABLE 语句(参见 清单 1
  • 使用带有一个 SAMEAS 子句的 CREATE EXTERNAL TABLE(参见 清单 2
  • 使用 SELECT 语句从一个数据源选择构成外部表的数据(参见 清单 3

清单 1 展示了第一种方法:

清单 1. 显式指定所有列
CREATE EXTERNAL TABLE et_state (code CHAR(2),sname CHAR(15))
USING (DATAFILES ("DISK:/data/NA_states.unl", "DISK:/data/SA_states.unl"));

清单 2 展示了第二种方法 — 从模板表复制。这种方法有以下几点注意事项:

  • 不复制在模板表的列上定义的约束。
  • 外部表 “et_state” 并不保持对模板表 “state” 的引用,即,state 表稍后有改动时,这个外部表不受影响。
  • 不复制模板表的 EXTERNAL 列指定,因此 FIXED 格式不能用于这种类型,原因是这种格式强制要求 EXTERNAL 列指定(EXTERNAL 列指定将在下面讨论)。
清单 2. 从 SAMEAS 模板表复制列及其类型
CREATE EXTERNAL TABLE et_state SAMEAS state
USING (DATAFILES ("DISK:/data/states.unl"));

清单 3 展示了第三种方法。这种方法有以下几点注意事项:

  • 如果 projection 列列表包含一个表达式,它必须拥有一个有效的列别名。
  • 不能使用 FIXED 格式,因为这种格式强制要求 EXTERNAL 列指定(EXTERNAL 列指定将在下面讨论),而这对这种格式是不可能的。
清单 3. 从选中的列派生列及其类型
SELECT * FROM state INTO EXTERNAL et_state
USING (DATAFILES ("DISK:/data/states.unl"));

支持的数据类型

外部表可以使用 IDS 中的常规基表支持的所有数据类型的列创建。使用 BLOB 和 CLOB 数据类型创建外部表时,建议提供 BLOBDIR 和 CLOBDIR,其中使用动态生成的文件名解压 BLOB 和 CLOB 数据。如果不指定这些条目,包含 BLOB 和 CLOB 数据的文件将解压缩到磁盘文件所在的对应目录中。

数据文件指定

除列指定之外,外部表的创建还包含一个 USING 子句。这个子句指定将用于这个外部表的(一个或多个)数据文件和表选项。

DATAFILES 是每个外部表的必需子句,它指定读写数据的文件路径。这里指定的路径的类型可以是 DISK 或 PIPE。另外,每个条目可以有一个可选的 BLOBDIR 和 CLOBDIR,用于指定读写 BLOB 和 CLOB 数据的位置。在该子句中可以指定多个文件。

DISK 文件使用 AIO 虚拟处理器(VP)访问,而 PIPE 文件通过 FIFO VPs 访问。DISK 文件是普通的文本文件或二进制文件,而 PIPE 文件是 FIFO 文件,通过在 UNIX® 上使用 mkfifomknod 命令创建(如下所示):

% mkfifo <filename>

% mknod <filename> p

其中:

  • filename 是 PIPE 文件的名称。
  • p 是文件的类型,表示 PIPE。

表选项

  • FORMAT:外部表可以采用 DELIMITED、FIXED 和 INFORMIX 格式之一。未指定 FORMAT 时,默认值为 DELIMITED。

    • DELIMITED:在 DATAFILES 中指定的数据文件是分隔开的。可以在 DELIMITER 表选项中指定分隔符。
    • FIXED:仅当创建外部表时在外部表列指定中使用 EXTERNAL 子句时才必须使用 FIXED 格式(参见 清单 18)。
    • INFORMIX:如果数据格式指定为 INFORMIX,从(到)文件的数据读(或写)将采用只能通过 Informix 解码的二进制格式。
  • DELUXEEXPRESSDEFAULT:加载数据时,可以指定这些选项中的一种来以相应的模式执行数据加载。DELUXE 在加载时向目标表提供更多并发性,而 EXPRESS 模式期望目标表是一个 RAW 表。DEFAULT 选项将决定权交给 IDS 服务器。
  • ESCAPE:如果分隔符用作数据值的一部分,则 ESCAPE 选项将转义那些来自数据的分隔符,以免将它们误解为分隔符。
  • DBDATE:外部数据文件中的日期列值采用由这个 DBDATE 指定的格式。如果不指定这个值,则数据库服务器使用在 DBDATE 环境变量中指定的日期格式。如果这两个值都没有指定,则采用数据库服务器的默认日期格式。
  • DBMONEY:外部数据文件中的货币列值的货币符号采用由 DBMONEY 指定的格式。如果不指定这个值,则数据库服务器使用在 DBMONEY 环境变量中指定的货币格式。如果这两个值都没有指定,则采用数据库服务器的默认货币格式。
  • DELIMITER:指定用于在分隔的文本文件中分隔字段的字符。默认的分隔符是竖线(|)。
  • RECORDEND:指定用于在分隔的文本文件中分隔记录的字符。默认值是行结束符。注意,这暗示着数据文件的新行将不解释为一个 “\n” 字符。如果 RECORDEND 指定为 “\n”,则相同的字符 “\n” 将会出现在数据文件中的每条记录之后。注意,DELIMITER 和 RECORDEND 都不适用于 FIXED 和 INFORMIX 格式。
  • MAXERRORS:设置数据库服务器停止加载之前允许的错误数量。
  • REJECTFILE:设置发生错误(比如数据转换错误)时 IDS 写入拒绝的行的完整路径。如果这个值没有指定或不能打开文件,任何加载错误都将导致操作异常终止。以下错误可能会导致一个行被拒绝:

    • CONVERT_ERR —— 任何字段遇到一个转换错误。
    • MISSING_DELIMITER —— 没有发现分隔符
    • MISSING_RECORDEND —— 没有发现记录结束符
    • NOT NULL —— 字段名中出现空值
    • ROW_TOO_LONG —— 输入记录太长
  • NUMROWS:外部表可能拥有的大致行数。在联接查询中使用外部表时,这个选项可能会改善性能。为了与 XPS 语法兼容,也可以使用 SIZE 替代 NUMROWS。

创建外部表:示例

要使用分隔符 “|” 创建与 customer 表具有相同表模式的外部表 “et_customer”,可以使用以下 DDL 语句:

清单 4. 创建外部表
CREATE EXTERNAL TABLE et_customer SAMEAS customer
USING (DATAFILES ("DISK:/data/americascust.dat"),DELIMITER "|");

从基表卸载

要将一个基表(例如 customer)中的数据卸载到一个外部表(使用前面的表定义抽象数据文件 /data/americascust.dat),可以使用以下命令:

清单 5. 卸载抽象数据文件的数据
INSERT INTO et_customer 
SELECT * FROM customer WHERE customer_num <= 110;

卸载后的文件 /data/americascust.dat 将包含:

清单 6. 卸载后的数据文件的内容
101|Ludwig|Pauli|All Sports Supplies|213 Erstwild Court||Sunnyvale|CA|94086|408-789-8075|
102|Carole|Sadler|Sports Spot|785 Geary St||San Francisco|CA|94117|415-822-1289|
103|Philip|Currie|Phil's Sports|654 Poplar|P. O. Box 3498|Palo Alto|CA|94303|415-328-4543|
104|Anthony|Higgins|Play Ball!|East Shopping Cntr.|422 Bay Road|Redwood City|CA|94026
     |415-368-1100|
105|Raymond|Vector|Los Altos Sports|1899 La Loma Drive||Los Altos|CA|94022|415-776-3249|
106|George|Watson|Watson & Son|1143 Carver Place||Mountain View|CA|94063|415-389-8789|
107|Charles|Ream|Athletic Supplies|41 Jordan Avenue||Palo Alto|CA|94304|415-356-9876|
108|Donald|Quinn|Quinn's Sports|587 Alvarado||Redwood City|CA|94063|415-544-8729|
109|Jane|Miller|Sport Stuff|Mayfair Mart|7345 Ross Blvd.|Sunnyvale|CA|94086|408-723-8789|
110|Roy|Jaeger|AA Athletics|520 Topaz Way||Redwood City|CA|94062|415-743-3611|

加载到基表

要将数据文件 /data/americascust.dat(此前已创建)中的数据加载到基表 customer,可以使用 INSERT 语句(如下所示):

INSERT INTO customer SELECT * FROM et_americascust;

从外部表选择

从外部表选择可从一个或多个数据文件读取数据,并以行和列的形式提供该数据,就好像从常规基表读取数据一样。还可以通过使用 WHERE 条件、ORDER BYGROUP BY 子句执行过滤操作,或者执行常规基表适用的其他操作。请参阅下面的 限制 小节了解更多细节。

清单 7 提供了一个示例查询,该查询用于列示新泽西州的所有客户姓名和电话号码:

清单 7. 列示所有 NJ(新泽西)客户姓名和电话号码
SELECT  RTRIM(fname) || ' ' || lname as fullname, phone
FROM et_americascust 
WHERE state = 'NJ';




fullname                        phone

Bob Shorter                     609-663-6079
Cathy O'Brian                   609-342-0054

用例

用例 1:使用与字符(&)作为分隔符,其中几行包含 & 作为一个数据值

  1. 使用以下 DDL 创建一个外部表:
    清单 8. 创建外部表
    CREATE EXTERNAL TABLE et_customer SAMEAS customer
    USING (DATAFILES ("DISK:/data/americascust.dat"), 
    
        DELIMITER "&",
        MAXERRORS 1,
        REJECTFILE "/tmp/reject.out");
  2. 使用清单 9 中的查询卸载 customer 基表中的数据:
    清单 9. 卸载 customer 基表中的数据
    INSERT INTO et_customer 
    SELECT * FROM customer WHERE customer_num <= 110;
    
    
    
    10 row(s) inserted.
    清单 10. 磁盘文件 /data/americascust.dat 的内容
    101&LudwigPauliAll Sports Supplies&213 Erstwild Court&&Sunnyvale&CA
         &94086&408-789-8075&
    102&Carole&Sadler&Sports Spot&785 Geary St&&San Francisco&CA&94117&415-822-1289&
    103&Philip&Currie&Phil's Sports&654 Poplar&P. O. Box 3498&Palo Alto
        &CA&94303&415-328-4543&
    104&Anthony&Higgins&Play Ball!&East Shopping Cntr.&422 Bay Road&
                    Redwood City&CA&94026&415-368-1100&
    105&Raymond&Vector&Los Altos Sports&1899 La Loma Drive&
         &Los Altos&CA&94022&415-776-3249&
    106&George&Watson&Watson & Son&1143 Carver Place&
         &Mountain View&CA&94063&415-389-8789&
    107&Charles&Ream&Athletic Supplies&41 Jordan Avenue&&Palo Alto&CA&94304&415-356-9876&
    108&Donald&Quinn&Quinn's Sports&587 Alvarado&&Redwood City&CA&94063&415-544-8729&
    109&Jane&Miller&Sport Stuff&Mayfair Mart&7345 Ross Blvd.
         &Sunnyvale&CA&94086&408-723-8789&
    110&Roy&Jaeger&AA Athletics&520 Topaz Way&&Redwood City&CA&94062&415-743-3611&
  3. 使用清单 11 中的查询选择外部表中的行:
    清单 11. 选择外部表中的行
    SELECT customer_num, rtrim(fname) || " " || lname as fullname, phone
    FROM     et_customer
    WHERE  customer_num <= 110;
    
    customer_num fullname                        phone              
    
             101 Ludwig Pauli                    408-789-8075      
             102 Carole Sadler                   415-822-1289      
             103 Philip Currie                   415-328-4543      
             104 Anthony Higgins                 415-368-1100      
             105 Raymond Vector                  415-776-3249      
    
    26197: Reached maximum error limit during load: (1).
    Error in line 5
    Near character position 23

    清单 11 中有几点需要引起注意:

    • customer_num 为 106 的行没有显示且查询中止,原因是该行包含数据 “Watson & son,”,其中分隔符 “&” 是数据的一部分。
    • 生成错误 26197。由于 MAXERRORS 的值指定为 1,因此第一个错误(其中 customer_num 为 106)本身就不能 “容忍”,因此查询中止。 如果 MAXERRORS 设置为 2 或更高,它还将显示 et_customer 中的其余 5 行。
    • 拒绝文件中包含了一个缺失的行。错误原因在于 “&”,这个已声明的分隔符也是数据的一部分,结果导致 customer_num = 106 的行拥有的列太多。

用例 2:转义用作分隔符的数据

USING 子句提供了一个 ESCAPE 选项来克服 用例 1 中描述的问题。

使用以下查询创建外部表:

清单 12. 创建外部表
CREATE EXTERNAL TABLE et_customer SAMEAS customer
USING (DATAFILES ("DISK:/data/americascust.dat"), 
    DELIMITER "&",
    ESCAPE,
    MAXERRORS 2,
    REJECTFILE "/tmp/reject.out");

数据文件中存储的已分隔且已转义的数据如下所示:

清单 13. 已分隔且已转义的数据
...

106&George&Watson&Watson \& Son&1143 Carver Place&&Mountain View&CA&94063&415-389-8789&
...

注意,用作数据的一部分的 “&” 已经使用一个反斜杠(\)进行转义。这一行现在可以通过一个外部表成功访问。

用例 3:使用 NUMROWS 获取更真实的估计和成本

NUMROWS 用于提供一个外部表可能拥有的大致行数。在使用联接查询时,优化器将使用这个信息来制定优化计划。

  1. 创建一个不带 NUMROWS 的外部表:
    清单 14. 创建不带 NUMROWS 的外部表
    CREATE EXTERNAL TABLE et_customer SAMEAS customer
    USING (DATAFILES ("DISK:/tmp/americascust.dat"),
        DELIMITER "|");
    
    INSERT INTO et_customer 
    SELECT * FROM customer;
    
    SET EXPLAIN ON;
    
    SELECT b.customer_num, a.fname, a.lname FROM et_customer a, orders b
    WHERE a.customer_num = b.customer_num and b.order_num lt; 1005
    
    sqexplain.out
    
    QUERY: (OPTIMIZATION TIMESTAMP: 01-15-2010 01:38:53)
    ------
    select b.customer_num, a.fname, a.lname from et_customer a, orders b
    where a.customer_num = b.customer_num and b.order_num lt; 1005
    
    
    Estimated Cost: 609062016
    Estimated # of Rows Returned: 631612864
    
      1) informix.a: SEQUENTIAL SCAN
    
      2) informix.b: INDEX PATH 
    
        (1) Index Name: informix. 102_3
            Index Keys: order_num   (Serial, fragments: ALL)
            Upper Index Filter: informix.b.order_num lt; 1005
    
    
    DYNAMIC HASH JOIN
        Dynamic Hash Filters: informix.a.customer_num = informix.b.customer_num
  2. 为了进行比较,创建一个带有 NUMROWS 的外部表:
    清单 15. 创建带有 NUMROWS 的外部表
    CREATE EXTERNAL TABLE et_customer SAMEAS customer
    USING (DATAFILES ("DISK:/tmp/americascust.dat"),
        DELIMITER "|", NUMROWS 28);	
    
    INSERT INTO et_customer 
    SELECT * FROM customer;
    
    SET EXPLAIN ON;
    
    SELECT b.customer_num, a.fname, a.lname FROM et_customer a, orders b
    WHERE a.customer_num = b.customer_num AND b.order_num lt; 1005
    
    sqexplain.out
    
    QUERY: (OPTIMIZATION TIMESTAMP: 01-15-2010 01:37:11)
    ------
    select b.customer_num, a.fname, a.lname from et_customer a, orders b
    where a.customer_num = b.customer_num and b.order_num lt; 1005
    
    Estimated Cost: 10
    Estimated # of Rows Returned: 8
    
      1) informix.a: SEQUENTIAL SCAN
    
      2) informix.b: INDEX PATH
    
        (1) Index Name: informix. 102_3
            Index Keys: order_num   (Serial, fragments: ALL)
            Upper Index Filter: informix.b.order_num lt; 1005

尽管这两个方案在这个简单的示例中是相同的,注意,估计的行和估计成本有巨大的差别,定义了 NUMROWS 的那个方案生成了更真实的估计值。涉及多个表时,这些估计值有助于获取更好的性能。

用例 4:使用不带 RAW 表的 EXPRESS 模式,并展示一个消息日志切换

假定我们在 USING 子句中使用 EXPRESS 模式。如果目标基表是一个非 RAW 表,当您将数据加载到这个基表时,IDS 将在内部将加载模式切换为 DELUXE。这个切换将记录到在线日志消息文件中,如清单 16 所示:

清单 16. 在线日志中的消息
...
12:20:53  Checkpoint Statistics - Avg. Txn Block Time 0.000, # Txns blocked 0, 
Plog used 30, Llog used 7
12:22:49  Switching load on target table informix.customer1 to DELUXE
...

指定的 EXPRESS 和 DELUXE 模式并不在所有用例中执行。执行加载操作时,这取决于目标表的类型和其他几个属性。因此,当 EXPRESS 模式被指定并在内部切换为 DELUXE 模式时,这样的信息就会记录在消息日志中;反之亦然。

用例 5:采用使用动态 SQL 和外部表的存储过程

清单 17. 在使用动态 SQL 的存储过程中创建外部表
CREATE PROCEDURE et_proc(tabname CHAR(128), et_tabname CHAR(128))
    DEFINE qry  CHAR(256);

    LET qry = "CREATE EXTERNAL TABLE" || et_tabname || "(code CHAR(2), name CHAR(15)) 
    USING (DATAFILES ("DISK:/data/tabdata.unl"))";
    EXECUTE IMMEDIATE qry;

    LET qry = "INSERT INTO" || et_tabname || "SELECT * FROM" || tabname;
    EXECUTE IMMEDIATE qry;

    LET qry = "DROP TABLE" || et_tabname;
    EXECUTE IMMEDIATE qry;
END PROCEDURE;

EXECUTE PROCEDURE et_proc;

外部表语句也可以用作静态语句。而且,从外部表选择可以获得准备并得以执行。下面即将讨论的所有 限制 都适用于存储过程语言。

存储过程中的外部表创建、访问、加载和卸载支持允许您更轻松地执行批加载和卸载操作。可以使用 dbcrons 特性,通过调用存储过程来调度加载和卸载操作。

用例 6:使用 FIXED 格式

使用 FIXED 格式时,必须对列使用 EXTERNAL 关键字。

清单 18. 创建 FIXED 格式的外部表
CREATE EXTERNAL TABLE et_customer (
    customer_num INT EXTERNAL CHAR(4), 
    fname CHAR(40) EXTERNAL CHAR(40))
    USING 
    (DATAFILES ("DISK:/data/cust.unl"), 
        FORMAT "FIXED", 
        REJECTFILE "/tmp/reject.out");

用例 7:使用用户定义类型(UDT)

清单 19 中的示例代码创建了一个明显的名为 “birthday” 的用户定义类型,并在创建外部表时用作列类型。类似地,其他 UDTs(比如 opaque 和 complex)也可用于外部表。

清单 19. 创建使用 UDT 的外部表
CREATE DISTINCT TYPE birthday AS DATE; 
CREATE EXTERNAL TABLE et_employee (empno CHAR(10), 
          empname VARCHAR(40), 
          empdob birthday)
USING (DATAFILES("DISK:/data/exployee.dat"),
 REJECTFILE "/tmp/reject.out");

限制

注意外部表的以下使用限制:

  • 不能含索引(因此也不能含有主键、惟一键和外键)。
  • 不能为外部表定义触发器。
  • 不能改变外部表模式。
  • 外部表不能是 MERGE 语句中的目标表。
  • 不能在主查询中使用多个外部表。
  • 不能在子查询中使用一个外部表。
  • 外部表数据文件不能进行任何形式的复制。
  • 不能针对一个外部表运行 UPDATE STATISTICS
  • 不能执行 UPDATEDELETE 操作。
  • LBAC 安全性不能施加在外部表数据文件上。
  • 外部数据文件不能压缩。
  • START/STOP VIOLATIONS 受限制。
  • 不能使用 Dbaccess 命令 LOAD FROM ... INSERT INTO 插入一个外部表。

无事务支持

外部表上的操作载入日志,因此,外部表上也不能实现事务支持。也就是说,外部表操作将对 BEGIN WORKCOMMIT/ROLLBACK WORK 语句置之不理。

由于不载入日志,外部表数据文件都不能进行复制。但是,在外部表创建时添加的系统目录数据仍将被复制。

MACH-11 环境

主服务器:在主服务器上允许外部表上的所有受支持操作。

次服务器:外部表在次服务器上的工作方式与在主服务器上类似,但有一点例外:不能在次服务器上创建外部表,原因是 MACH-11 环境中的次服务器上不支持 DDL。 数据的加载和卸载可以从次服务器完成。但是,有一点应该引起注意:在次服务器上将数据从外部表导入基表的操作与在主服务器上执行相同的操作相比,操作性能可能要低一些。这是因为次服务器上的更新将被转发到主服务器以执行实际操作。在主服务器和次服务器中创建的数据文件不会被复制到其他服务器,根据需要将这些文件复制到其他服务器是用户的责任。

安全性

用于访问外部表的权限由 IDS 通过外部表上的用户访问特权治理,还受到由操作系统管理的数据文件权限的治理。这意味着表创建者将拥有对外部表的访问权限,还必须拥有对与外部表关联的数据文件的适当访问权限。注意,在外部表创建之时,与该外部表关联的数据文件不需要存在。因此,创建者应该负责确保数据文件具有适当的权限,以便在外部表上执行选择或插入操作。要使用外部表,任何用户必须对外部表和数据文件拥有访问特权。另外,尽管对底层文件拥有全部特权,但是通过 GRANTREVOKE 语句,用户仍然可以从数据库服务器内部控制对外部表的访问。用户可以授予(GRANT)和调用(REVOKE)外部表上的 SELECT 或 INSERT 特权。授予或调用外部表上的特权并不会对关联数据文件权限造成任何影响。

系统目录

对于每个数据库,11.50.xC6(或更高版本)中将额外创建三个新系统目录:

  • Sysexternal
  • Sysextdfiles
  • Sysextcols

这些目录表用于存储本文讨论的表选项、数据文件和外部列。

性能

外部表是 IDS 的一部分,它使用一些算法同时执行加载和卸载操作。因此,与其他基于客户机的工具相比,预期性能应该好一些。

为改善性能,加载操作在适用时将使用 “轻追加法(light append)”。如果将从外部表加载数据所到的基表定义为不带索引的 RAW 表,则 IDS 服务器将使用 “轻追加法” 加载数据。

在基表上执行任何操作之前,必须对执行 “轻追加法” 的表备份。这种行为类似于高性能加载器使用 “轻追加法” 加载数据时的行为。

当多个外部表定义多个数据文件且 PDQ 设置为 ON 时,所有这些文件将被并行访问以供加载器所需,这将改善性能。

迁移

由于新版本为外部表增加了新的系统目录表,IDS 服务器的旧版本(11.50.xC5 或更早)必须经过一个自动转换过程,方法是使用此前的 “rootdbs”(在您的 onconfig 文件中查找 ROOTNAME 条目)以无需重新初始化的方式启动 IDS 11.50.xC6 服务器(或更高版本)。IDS 11.50.xC6(或更高版本)将把所有数据库进行适当转换以包含这些新的系统目录表。与这些外部表关联的数据文件不会受到任何更改。

类似地,要从 IDS 11.50.xC6(或更高版本)恢复到任何旧版本,必须执行一个逆转过程。删除所有外部表后,在 IDS 11.50.xC6 服务器上运行以下命令,执行一些步骤以恢复版本 11.50.xC5:

% onmode b 11.50.xC5

注意,新的系统目录表将在逆转过程中删除。

原则和最佳实践

使用外部表时要获得最佳结果,请遵循以下最佳实践:

  • 在次服务器(最好是只读的)上卸载数据。
  • 在非高峰期间在主服务器上加载数据。
  • 在模式创建脚本中使用 SAMEAS 子句。
  • 有明确的分隔符和转义选项可供使用。
  • 使用多个文件、而不是一个超大文件定义外部表;使用 PDQ 优先集执行加载或选择操作,以便 IDS 利用 “并行性”。
  • 加载时,如果目标基表被碎片化(fragmented),加载过程将在 PDQ 环境下并行发生。
  • 外部表中的管道可用于在两个实例之间转移数据并在磁盘空间上保存数据。

结束语

外部表特性提供了一种简单直观的方法来通过 SQL 界面或存储过程执行加载和卸载操作。对底层数据文件应用表抽象使无缝应用 SQL 操作变得更加轻松。另外,各种格式、分隔符、日期和货币格式能够满足来自任意数据源和任意地理位置的数据文件的要求。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=493378
ArticleTitle=借助 Informix Dynamic Server 中的外部表特性使用数据文件抽象
publish-date=05312010