创建 Flex 表

您无需列定义或其他参数即可创建 Flex 表或外部 Flex 表。您可以像往常一样使用您喜欢的任何 CREATE TABLE 语句参数。

创建基本 Flex 表

创建该表的方法如下:

=> CREATE FLEX TABLE darkdata();
CREATE TABLE

在将任何数据加载到表中之前从表中进行选择将显示其两个实际列 — __identity____raw__

=> SELECT * FROM darkdata;
__identity__    | __raw__
--------------+---------
(0 rows)

以下为一个用列定义创建 Flex 表的示例:

=> CREATE FLEX TABLE darkdata1(name VARCHAR);
CREATE TABLE

当 Flex 表存在时,您可以按照实体化 Flex 表中所述,添加新的列(包括那些具有默认派生表达式的列)。

实体化 Flex 表虚拟列

创建 Flex 表并加载数据后,您可以从虚拟列中计算出键。完成这些任务后,您可以通过将虚拟列提升为实际表列,而将某些键实体化。提升虚拟列使您可以查询实际列,而不是原始数据。

您可以提升一个或多个虚拟列 — 从而将那些键从 __raw__ 数据内部实体化到实际列。Vertica 建议使用此方法来获取所有重要键的最佳查询性能。您无需从 Flex 表创建新的列式表。

实体化 Flex 表列将导致出现混合表。混合表:

  • 可保留 Flex 表加载非结构化数据时的便利性

  • 可提高任何实际列的查询性能

如果您仅有少量几列可以实体化,请尝试逐步更改 Flex 表,并在必要时添加列。您可以使用 ALTER TABLE...ADD COLUMN 语句执行此操作,就像您将对列式表执行此操作一样。请参阅实体化 Flex 表,了解有关添加列的技巧。

如果您希望自动将列实体化,请使用 Helper 函数 MATERIALIZE_FLEXTABLE_COLUMNS

从 Flex 表创建列式表

您可以从 Flex 表创建常规 Vertica 表,但您不能使用一个 Flex 表创建另一个 Flex 表。

通常情况下,您在加载数据后从 Flex 表创建列式表。然后,您可以指定您希望出现在常规表中的虚拟列数据,将虚拟列转换成常规数据类型。

要从 Flex 表 darkdata 创建列式表,请为新表选择两个虚拟列(user.languser.name)。使用针对新表将两个列均转换成 varchars 的如下命令:

=> CREATE TABLE darkdata_full AS SELECT "user.lang"::VARCHAR, "user.name"::VARCHAR FROM darkdata;
CREATE TABLE
=> SELECT * FROM darkdata_full;
 user.lang |      user.name
-----------+---------------------
 en        | Frederick Danjou
 en        | The End
 en        | Uptown gentleman.
 en        | ~G A B R I E L A â¿
 es        | Flu Beach
 es        | I'm Toasterâ¥
 it        | laughing at clouds.
 tr        | seydo shi
           |
           |
           |
           |
(12 rows)

创建临时 Flex 表

在创建临时全局和本地 Flex 表之前,请了解以下注意事项:

  • 支持全局临时 (GLOBAL TEMP) Flex 表。创建临时全局 Flex 表将导致 flextable_keys 表和 flextable_view 具有针对其内容的临时表限制。

  • 本地临时 (LOCAL TEMP) Flex 表必须包括至少一个列定义。做此要求的原因是,本地临时表不支持自动递增数据(如 Flex 表默认的 __identity__ 列)。创建临时本地 Flex 表将导致 flextable_keys 表和 flextable_view 存在于本地临时对象范围中。

  • 支持 Flex 和列式临时表的本地临时 (LOCAL TEMP) 视图。

要想全局或本地临时 Flex 表正常工作,您还必须指定 ON COMMIT PRESERVE ROWS 子句。您必须将 ON COMMIT 子句用于依靠提交的 Flex 表 Helper 函数。按照如下方式创建本地临时表:

=> CREATE FLEX LOCAL TEMP TABLE good(x int) ON COMMIT PRESERVE ROWS;
CREATE TABLE

使用此方法创建本地临时 Flex 表后,即可将数据加载到表中,创建表键和 Flex 表视图:

=> COPY good FROM '/home/release/KData/bake.json' PARSER fjsonparser();
 Rows Loaded
-------------
           1
(1 row)

=> select compute_flextable_keys_and_build_view('good');
                            compute_flextable_keys_and_build_view
----------------------------------------------------------------------------------------------
 Please see v_temp_schema.good_keys for updated keys
The view good_view is ready for querying
(1 row)

同样地,您可以按照如下方式创建全局临时表:

=> CREATE FLEX GLOBAL TEMP TABLE good_global(x int) ON COMMIT PRESERVE ROWS;

使用此方法创建全局临时 Flex 表后,即可将数据加载到表中,创建表键和 Flex 表视图:

=> COPY good_global FROM '/home/dbadmin/data/flex/bake_single.json' PARSER fjsonparser();
Rows Loaded
-------------
5
(1 row)

=> SELECT compute_flextable_keys_and_build_view('good_global');
                            compute_flextable_keys_and_build_view
----------------------------------------------------------------------------------------------
 Please see v_temp_schema.good_keys for updated keys
The view good_view is ready for querying
(1 row)

创建外部 Flex 表

要创建外部 Flex 表:

=> CREATE flex external table mountains() AS COPY FROM 'home/release/KData/kmm_ountains.json' PARSER fjsonparser();
CREATE TABLE

与其他 Flex 表一样,创建外部 Flex 表会生成两个常规表:命名表及其关联的 _keys 表。键表不是外部表:

=> \dt mountains
                 List of tables
 Schema |   Name    | Kind  |  Owner  | Comment
--------+-----------+-------+---------+---------
 public | mountains | table | release |
(1 row)

可以使用帮助程序函数 COMPUTE_FLEXTABLE_KEYS_AND_BUILD_VIEW 计算键并创建外部表视图:

=> SELECT compute_flextable_keys_and_build_view ('appLog');

                     compute_flextable_keys_and_build_view
--------------------------------------------------------------------------------------------------
Please see public.appLog_keys for updated keys
The view public.appLog_view is ready for querying
(1 row)

检查 _keys 表中的键,以获取帮助应用程序的运行结果:

=> SELECT * FROM appLog_keys;
                          key_name                       | frequency |   data_type_guess
----------------------------------------------------------+-----------+------------------
contributors                                             |         8 | varchar(20)
coordinates                                              |         8 | varchar(20)
created_at                                               |         8 | varchar(60)
entities.hashtags                                        |         8 | long varbinary(186)
.
.
.
retweeted_status.user.time_zone                          |         1 | varchar(20)
retweeted_status.user.url                                |         1 | varchar(68)
retweeted_status.user.utc_offset                         |         1 | varchar(20)
retweeted_status.user.verified                           |         1 | varchar(20)
(125 rows)

您可以查询视图:

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

从查询结果创建 Flex 表

您可以使用 CREATE FLEX TABLE AS 语句从查询结果创建 Flex 表。

您可以使用此语句创建三种类型的 Flex 表:

  • 没有实体化列的 Flex 表

  • 带有一些实体化列的 Flex 表

  • 带有所有实体化列的 Flex 表


当 CTAS 查询中存在 Flex __raw__ 列时,整个源 VMap 将被传送到 Flex 表中。如果查询具有匹配的列名,则键值将被覆盖。

示例

从常规表创建没有实体化列的 Flex 表会导致查询结果作为 VMap 存储在 __raw__ 列中。

  1. 创建名为 pets 的包含两列的常规表:

    => CREATE TABLE pets(age INT, name VARCHAR);
    CREATE TABLE
    
  2. 通过使用 CTAS 语句从 pets 复制列 agename,创建名为 family_pets 的 Flex 表:

    => CREATE FLEX TABLE family_pets() AS SELECT age, name FROM pets;
    CREATE TABLE
    
  3. 查看新的 Flex 表以确认操作已成功,并且列 agename 尚未实体化。

    => \d family_pets;
        List of Fields by Tables
    Schema | Table       |    Column    |          Type          |  Size  | Default | Not Null | Primary Key | Foreign Key
    --------+------------+--------------+------------------------+--------+---------+----------+-------------+-------------
    public | family_pets | __identity__ | int                    |      8 |         | t        | f           |
    public | family_pets | __raw__      | long varbinary(130000) | 130000 |         | t        | f           |
    (2 rows)
    

    您可以从另一个 Flex 表的查询结果中创建一个没有实体化列的 Flex 表。这会将源 Flex 表中的所有 VMap 插入到目标中。这将创建一个按 __identity__ 列分段和排序的 Flex 表。

  4. 通过使用 CTAS 语句从 family_pets 复制 age__raw__ 列,创建名为 city_pets 的 Flex 表:

    => CREATE FLEX TABLE city_pets() AS SELECT age, __raw__ FROM family_pets;
    CREATE TABLE
    
  5. 查看新的 Flex 表以确认操作已成功,并且列 age__raw__ 尚未实体化。

    => SELECT * FROM city_pets;
        List of Fields by Tables
    Schema | Table     |    Column    |          Type          |  Size  | Default | Not Null | Primary Key | Foreign Key
    --------+----------+--------------+------------------------+--------+---------+----------+-------------+-------------
    public | city_pets | __identity__ | int                    |      8 |         | t        | f           |
    public | city_pets | __raw__      | long varbinary(130000) | 130000 |         | t        | f           |
    (2 rows)
    

    您可以创建包含一些实体化列的 Flex 表。使用的语法类似于用于创建具有一些实体化列的列式表的语法。但是,与列式表不同,您需要将列数与查询返回的列相匹配。在以下示例中,查询返回三列(amounttypeavailable),但 Vertica 仅实体化前两列。

  6. 创建名为 animals 的包含三列(amounttypeavailable)的表:

    => CREATE TABLE animals(amount INT, type VARCHAR, available DATE);
    
  7. 通过使用 CTAS 语句从 animals 复制 amounttypeavailable 列,创建名为 inventory 的包含 animal_amountanimal_type 列的 Flex 表:

    => CREATE FLEX TABLE inventory(animal_amount, animal_type) AS SELECT amount, type, available FROM animals;
    CREATE TABLE
    
  8. 查看表数据以确认 amounttype 列已在列名称 animal_amountanimal_type 下实体化。animals 中的列 available 也已被复制,但未实体化:

    => \d inventory
        List of Fields by Tables
    Schema | Table | Column           |          Type          |  Size  | Default | Not Null | Primary Key | Foreign Key
    --------+-------+-----------------+------------------------+--------+---------+---------+-------------+-------------
    public | flex3 | __raw__          | long varbinary(130000) | 130000 |         | t       | f           |
    public | flex3 | animal_amount    | int                    |      8 |         | f       | f           |
    public | flex3 | animal_type      | varchar(80)            |     80 |         | f       | f           |
    (3 rows)
    

    请注意,在语句中包含空括号会生成一个没有实体化列的 Flex 表:

  9. 使用带空括号的 CTAS 语句创建名为 animals_for_sale 的 Flex 表,以将列 amounttypeavailableanimals 复制到纯 Flex 表:

    => CREATE FLEX TABLE animals__for_sale() AS SELECT amount, type, available FROM animals;
    CREATE TABLE
    
  10. 查看表数据以确认没有任何列实体化:

    =>\d animals_for_sale;
        List of Fields by Tables
    Schema | Table            |    Column    |          Type          |  Size  | Default | Not Null | Primary Key | Foreign Key
    --------+-----------------+--------------+------------------------+--------+---------+----------+------------+-------------
    public | animals_for_sale | __identity__ | int                    |      8 |         | t        | f          |
    public | animals_for_sale | __raw__      | long varbinary(130000) | 130000 |         | t        | f          |
    
    (2 rows)
    

    在语句中省略任何括号会导致所有列均实体化:

  11. 使用不带括号的 CTAS 语句创建名为 animals_sold 的 Flex 表。这会从 animals 复制列 amounttypeavailable 并实体化所有列:

    => CREATE FLEX TABLE animals_sold AS SELECT amount, type, available FROM animals;
    CREATE TABLE
    
  12. 查看表数据以确认所有列均实体化:

    => \d animals_sold;
        List of Fields by Tables
    Schema | Table        | Column    |          Type          |  Size  | Default | Not Null | Primary Key | Foreign Key
    --------+-------------+-----------+------------------------+--------+---------+----------+-------------+-------------
    public | animals_sold | __raw__   | long varbinary(130000) | 130000  |         | t        | f           |
    public | animals_sold | amount    | int                    |      8  |         | f        | f           |
    public | animals_sold | type      | varchar(80)            |     80  |         | f        | f           |
    public | animals_sold | available | date                   |      8  |         | f        | f           |
    (4 rows)