将数据批量加载到 Flex 表中

您可以指定下列 Flex 解析器之一,并使用 COPY 语句将数据批量加载到 Flex 表中:

  • FAVROPARSER

  • FCEFPARSER

  • FCSVPARSER

  • FDELIMITEDPAIRPARSER

  • FDELIMITEDPARSER

  • FJSONPARSER

  • FREGEXPARSER

所有 Flex 解析器均将数据存储为单值 VMap。它们驻留在 VARBINARY__raw__ 列,该列为具有 NOT NULL 约束的实际列。VMap 编码为单一二进制值,以便存储在 __raw__ 列中。编码将值字符串置于连续区块中,后面是键字符串。Vertica 针对带 NULL 指定列的键,支持 VMap 内的 NULL 值。键和值字符串分别代表 Flex 表中的虚拟列和它们的值。

如果 Flex 表数据行太大而无法适应 __raw__ 列,该数据行将被拒绝。默认情况下,被拒数据和异常文件存储在标准 CopyErrorLogs 位置,这是编录目录的一个子目录:

v_mart_node003_catalog/CopyErrorLogs/trans-STDIN-copy-from-exceptions.1
v_mart_node003_catalog/CopyErrorLogs/trans-STDIN-copy-rejections.1

出于对磁盘空间的考虑,Flex 表不会复制任何被拒数据。被拒数据文件存在,但对于每个被拒记录,仅包含一个换行符。相应的异常文件列出了每个记录被拒绝的原因。

您可以为被拒数据文件和异常文件指定一个不同的路径和文件。为此,请分别使用 COPY 选项 REJECTED DATAEXCEPTIONS。您还可以将加载拒绝和异常情况保存在表中。有关详细信息,请参阅数据加载

基本 Flex 表加载和查询

将数据加载到 Flex 表中与将数据加载到常规列式表中类似。差别在于,您必须在使用其中一种 Flex 解析器的同时使用 PARSER 选项:

=> COPY darkdata FROM '/home/dbadmin/data/tweets_12.json' PARSER fjsonparser();
 Rows Loaded
-------------
          12
(1 row)

将数据加载到 Flex 表的实际列

如果您创建具有一个或多个实际列定义的混合 Flex 表,则 COPY 在数据加载期间评估每个虚拟列键名,并使用来自对应虚拟列的值自动填充实际列。对于标量类型的列,COPY 还将键和值作为 VMap 数据的一部分加载到 __raw__ 列。对于复杂类型的列,COPY 不会将值添加到 __raw__ 列。

例如,继续使用 JSON 示例:

  1. 创建 Flex 表,该表具有待加载数据中一个键的列定义:

    => CREATE FLEX TABLE darkdata1 ("user.lang" VARCHAR);
    CREATE TABLE
    
  2. 将数据加载到表中:

    => COPY darkdata1 FROM '/test/vertica/flextable/DATA/tweets_12.json' PARSER fjsonparser();
     Rows Loaded
    -------------
              12
    (1 row)
    
  3. 直接查询实际列:

    => SELECT "user.lang" FROM darkdata1;
     user.lang
    -----------
     es
     es
     tr
     it
     en
     en
     en
     en
    (12 rows)
    

    实体化列中的空行指示 NULL 值。有关如何在 Flex 表中处理 NULL 值的详细信息,请参阅 NULL 值

  4. 您可以查询其他具有类似结果的虚拟列:

    => SELECT "user.name" FROM darkdata1;
          user.name
    ---------------------
     I'm Toasterâ¥
     Flu Beach
     seydo shi
     The End
     Uptown gentleman.
     ~G A B R I E L A â¿
     Frederick Danjou
     laughing at clouds.
    (12 rows)
    

在加载过程中处理默认值

您可以创建具有一个实际列的 Flex 表,该实际列以传入数据中存在的一个虚拟列命名。例如,如果您加载的数据包含一个 user.lang 虚拟列,请用该列定义 Flex 表。您还可以在创建具有实际列的 Flex 表时,指定默认列值。下个示例演示了如何定义具有来自虚拟列 (user.name) 的默认值的实际列 (user.lang):

=> CREATE FLEX TABLE darkdata1 ("user.lang" LONG VARCHAR default "user.name");

将数据加载到 Flex 表中时,COPY 使用 Flex 表数据中的值,忽略默认列定义。要将数据加载到 Flex 表中,需要通过 MAPLOOKUP 找到与任何实际列名称相匹配的键。如果传入数据中具有名称与某个实际列相同的虚拟列,则存在匹配项。当 COPY 检测到匹配项时,它将用值填充该列。COPY 针对各行返回值或 NULL,因此实际列始终具有值。

例如,如前面的示例所述创建 Flex 表后,使用 COPY 加载数据:


=> COPY darkdata1 FROM '/test/vertica/flextable/DATA/tweets_12.json' PARSER fjsonparser();
 Rows Loaded
-------------
          12
(1 row)

如果您在加载后查询表,数据显示已提取 user.lang 列的值:

  • 来自正在加载的数据 — user.lang 虚拟列的值

  • NULL — 没有值的行

在这种情况下,user.lang 的表列默认值被忽略:

=> SELECT "user.lang" FROM darkdata1;
 user.lang
-----------
 it
 en
 es
 en
 en
 es
 tr
 en
(12 rows)

使用 COPY 指定默认列值

您可以将表达式添加到 COPY 语句,以便在加载数据时指定默认列值。对于 Flex 表,如要指定任何列信息,您需要显示列出 __raw__ 列。以下示例演示了如何使用默认列值的表达式。在这种情况下,加载数据即可用输入数据 user.name 的值填充已定义的 user.lang 列:

=> COPY darkdata1(__raw__, "user.lang" as "user.name"::VARCHAR)
   FROM '/test/vertica/flextable/DATA/tweets_12.json' PARSER fjsonparser();
 Rows Loaded
-------------
          12
(1 row)
=> SELECT "user.lang" FROM darkdata1;
      user.lang
---------------------
 laughing at clouds.
 Avita Desai
 I'm Toasterâ¥
 Uptown gentleman.
 ~G A B R I E L A â¿
 Flu Beach
 seydo shi
 The End
(12 rows)

您可以按照更改 Flex 表中的说明,在添加列时指定默认值。执行此操作将导致不同的行为。有关使用 COPY、其表达式和参数的详细信息,请参阅数据加载COPY 参考页面。