CREATE 语句用于向当前或指定的 Catalog 中注册表、视图或函数。注册后的表、视图和函数可以在 SQL 查询中使用。
目前 Flink SQL 支持下列 CREATE 语句:
可以使用 TableEnvironment
中的 executeSql()
方法执行 CREATE 语句。 若 CREATE 操作执行成功,executeSql()
方法返回 ‘OK’,否则会抛出异常。
以下的例子展示了如何在 TableEnvironment
中执行一个 CREATE 语句。
可以使用 TableEnvironment
中的 execute_sql()
方法执行 CREATE 语句。 若 CREATE 操作执行成功,execute_sql()
方法返回 ‘OK’,否则会抛出异常。
以下的例子展示了如何在 TableEnvironment
中执行一个 CREATE 语句。
可以在 SQL CLI 中执行 CREATE 语句。
以下的例子展示了如何在 SQL CLI 中执行一个 CREATE 语句。
根据指定的表名创建一个表,如果同名表已经在 catalog 中存在了,则无法注册。
Physical / Regular Columns
Physical columns are regular columns known from databases. They define the names, the types, and the order of fields in the physical data. Thus, physical columns represent the payload that is read from and written to an external system. Connectors and formats use these columns (in the defined order) to configure themselves. Other kinds of columns can be declared between physical columns but will not influence the final physical schema.
The following statement creates a table with only regular columns:
Metadata Columns
Metadata columns are an extension to the SQL standard and allow to access connector and/or format specific
fields for every row of a table. A metadata column is indicated by the METADATA
keyword. For example,
a metadata column can be be used to read and write the timestamp from and to Kafka records for time-based
operations. The connector and format documentation lists the
available metadata fields for every component. However, declaring a metadata column in a table’s schema
is optional.
The following statement creates a table with an additional metadata column that references the metadata field timestamp
:
Every metadata field is identified by a string-based key and has a documented data type. For example,
the Kafka connector exposes a metadata field with key timestamp
and data type TIMESTAMP(3) WITH LOCAL TIME ZONE
that can be used for both reading and writing records.
In the example above, the metadata column record_time
becomes part of the table’s schema and can be
transformed and stored like a regular column:
For convenience, the FROM
clause can be omitted if the column name should be used as the identifying metadata key:
For convenience, the runtime will perform an explicit cast if the data type of the column differs from the data type of the metadata field. Of course, this requires that the two data types are compatible.
By default, the planner assumes that a metadata column can be used for both reading and writing. However,
in many cases an external system provides more read-only metadata fields than writable fields. Therefore,
it is possible to exclude metadata columns from persisting using the VIRTUAL
keyword.
In the example above, the offset
is a read-only metadata column and excluded from the query-to-sink
schema. Thus, source-to-query schema (for SELECT
) and query-to-sink (for INSERT INTO
) schema differ:
Computed Columns
Computed columns are virtual columns that are generated using the syntax column_name AS computed_column_expression
.
A computed column evaluates an expression that can reference other columns declared in the same table. Both physical columns and metadata columns can be accessed if they preceed the computed column in the schema declaration. The column itself is not physically stored within the table. The column’s data type is derived automatically from the given expression and does not have to be declared manually.
The planner will transform computed columns into a regular projection after the source. For optimization or watermark strategy push down, the evaluation might be spread across operators, performed multiple times, or skipped if not needed for the given query.
For example, a computed column could be defined as:
The expression may contain any combination of columns, constants, or functions. The expression cannot contain a subquery.
Computed columns are commonly used in Flink for defining time attributes
in CREATE TABLE
statements.
proc AS PROCTIME()
using the system’s PROCTIME()
function.WATERMARK
declaration. For example, the computed column can be used
if the original field is not TIMESTAMP(3)
type or is nested in a JSON string.Similar to virtual metadata columns, computed columns are excluded from persisting. Therefore, a computed
column cannot be the target of an INSERT INTO
statement. Thus, source-to-query schema (for SELECT
)
and query-to-sink (for INSERT INTO
) schema differ:
WATERMARK
WATERMARK
定义了表的事件时间属性,其形式为 WATERMARK FOR rowtime_column_name AS watermark_strategy_expression
。
rowtime_column_name
把一个现有的列定义为一个为表标记事件时间的属性。该列的类型必须为 TIMESTAMP(3)
,且是 schema 中的顶层列,它也可以是一个计算列。
watermark_strategy_expression
定义了 watermark 的生成策略。它允许使用包括计算列在内的任意非查询表达式来计算 watermark ;表达式的返回类型必须是 TIMESTAMP(3)
,表示了从 Epoch 以来的经过的时间。
返回的 watermark 只有当其不为空且其值大于之前发出的本地 watermark 时才会被发出(以保证 watermark 递增)。每条记录的 watermark 生成表达式计算都会由框架完成。
框架会定期发出所生成的最大的 watermark ,如果当前 watermark 仍然与前一个 watermark 相同、为空、或返回的 watermark 的值小于最后一个发出的 watermark ,则新的 watermark 不会被发出。
Watermark 根据 pipeline.auto-watermark-interval
中所配置的间隔发出。
若 watermark 的间隔是 0ms
,那么每条记录都会产生一个 watermark,且 watermark 会在不为空并大于上一个发出的 watermark 时发出。
使用事件时间语义时,表必须包含事件时间属性和 watermark 策略。
Flink 提供了几种常用的 watermark 策略。
严格递增时间戳: WATERMARK FOR rowtime_column AS rowtime_column
。
发出到目前为止已观察到的最大时间戳的 watermark ,时间戳大于最大时间戳的行被认为没有迟到。
递增时间戳: WATERMARK FOR rowtime_column AS rowtime_column - INTERVAL '0.001' SECOND
。
发出到目前为止已观察到的最大时间戳减 1 的 watermark ,时间戳大于或等于最大时间戳的行被认为没有迟到。
有界乱序时间戳: WATERMARK FOR rowtime_column AS rowtime_column - INTERVAL 'string' timeUnit
。
发出到目前为止已观察到的最大时间戳减去指定延迟的 watermark ,例如, WATERMARK FOR rowtime_column AS rowtime_column - INTERVAL '5' SECOND
是一个 5 秒延迟的 watermark 策略。
PRIMARY KEY
主键用作 Flink 优化的一种提示信息。主键限制表明一张表或视图的某个(些)列是唯一的并且不包含 Null 值。 主键声明的列都是非 nullable 的。因此主键可以被用作表行级别的唯一标识。
主键可以和列的定义一起声明,也可以独立声明为表的限制属性,不管是哪种方式,主键都不可以重复定义,否则 Flink 会报错。
有效性检查
SQL 标准主键限制可以有两种模式:ENFORCED
或者 NOT ENFORCED
。 它申明了是否输入/出数据会做合法性检查(是否唯一)。Flink 不存储数据因此只支持 NOT ENFORCED
模式,即不做检查,用户需要自己保证唯一性。
Flink 假设声明了主键的列都是不包含 Null 值的,Connector 在处理数据时需要自己保证语义正确。
Notes: 在 CREATE TABLE 语句中,创建主键会修改列的 nullable 属性,主键声明的列默认都是非 Nullable 的。
PARTITIONED BY
根据指定的列对已经创建的表进行分区。若表使用 filesystem sink ,则将会为每个分区创建一个目录。
WITH
Options表属性用于创建 table source/sink ,一般用于寻找和创建底层的连接器。
表达式 key1=val1
的键和值必须为字符串文本常量。请参考 连接外部系统 了解不同连接器所支持的属性。
注意: 表名可以为以下三种格式 1. catalog_name.db_name.table_name
2. db_name.table_name
3. table_name
。使用catalog_name.db_name.table_name
的表将会与名为 “catalog_name” 的 catalog 和名为 “db_name” 的数据库一起注册到 metastore 中。使用 db_name.table_name
的表将会被注册到当前执行的 table environment 中的 catalog 且数据库会被命名为 “db_name”;对于 table_name
, 数据表将会被注册到当前正在运行的catalog和数据库中。
注意: 使用 CREATE TABLE
语句注册的表均可用作 table source 和 table sink。 在被 DML 语句引用前,我们无法决定其实际用于 source 抑或是 sink。
LIKE
LIKE
子句来源于两种 SQL 特性的变体/组合(Feature T171,“表定义中的 LIKE 语法” 和 Feature T173,“表定义中的 LIKE 语法扩展”)。LIKE 子句可以基于现有表的定义去创建新表,并且可以扩展或排除原始表中的某些部分。与 SQL 标准相反,LIKE 子句必须在 CREATE 语句中定义,并且是基于 CREATE 语句的更上层定义,这是因为 LIKE 子句可以用于定义表的多个部分,而不仅仅是 schema 部分。
你可以使用该子句,重用(或改写)指定的连接器配置属性或者可以向外部表添加 watermark 定义,例如可以向 Apache Hive 中定义的表添加 watermark 定义。
示例如下:
结果表 Orders_with_watermark
等效于使用以下语句创建的表:
表属性的合并逻辑可以用 like options
来控制。
可以控制合并的表属性如下:
并且有三种不同的表属性合并策略:
并且你可以使用 INCLUDING/EXCLUDING ALL
这种声明方式来指定使用怎样的合并策略,例如使用 EXCLUDING ALL INCLUDING WATERMARKS
,那么代表只有源表的 WATERMARKS 属性才会被包含进新表。
示例如下:
如果未提供 like 配置项(like options),默认将使用 INCLUDING ALL OVERWRITING OPTIONS
的合并策略。
注意: 您无法选择物理列的合并策略,当物理列进行合并时就如使用了 INCLUDING
策略。
注意: 源表 source_table
可以是一个组合 ID。您可以指定不同 catalog 或者 DB 的表作为源表: 例如,my_catalog.my_db.MyTable
指定了源表 MyTable
来源于名为 MyCatalog
的 catalog 和名为 my_db
的 DB ,my_db.MyTable
指定了源表 MyTable
来源于当前 catalog 和名为 my_db
的 DB。
Create a catalog with the given catalog properties. If a catalog with the same name already exists, an exception is thrown.
WITH OPTIONS
Catalog properties used to store extra information related to this catalog.
The key and value of expression key1=val1
should both be string literal.
Check out more details at Catalogs.
根据给定的表属性创建数据库。若数据库中已存在同名表会抛出异常。
IF NOT EXISTS
若数据库已经存在,则不会进行任何操作。
WITH OPTIONS
数据库属性一般用于存储关于这个数据库额外的信息。
表达式 key1=val1
中的键和值都需要是字符串文本常量。
根据给定的 query 语句创建一个视图。若数据库中已经存在同名视图会抛出异常.
TEMPORARY
创建一个有 catalog 和数据库命名空间的临时视图,并覆盖原有的视图。
IF NOT EXISTS
若该视图已经存在,则不会进行任何操作。
创建一个有 catalog 和数据库命名空间的 catalog function ,需要指定一个 identifier ,可指定 language tag 。 若 catalog 中,已经有同名的函数注册了,则无法注册。
如果 language tag 是 JAVA 或者 SCALA ,则 identifier 是 UDF 实现类的全限定名。关于 JAVA/SCALA UDF 的实现,请参考 自定义函数。
如果 language tag 是 PYTHON,则 identifier 是 UDF 对象的全限定名,例如 pyflink.table.tests.test_udf.add
。关于 PYTHON UDF 的实现,请参考 Python UDFs。
如果 language tag 是 PYTHON,而当前程序是 Java/Scala 程序或者纯 SQL 程序,则需要配置 Python 相关的依赖。
TEMPORARY
创建一个有 catalog 和数据库命名空间的临时 catalog function ,并覆盖原有的 catalog function 。
TEMPORARY SYSTEM
创建一个没有数据库命名空间的临时系统 catalog function ,并覆盖系统内置的函数。
IF NOT EXISTS
若该函数已经存在,则不会进行任何操作。
LANGUAGE JAVA|SCALA|PYTHON
Language tag 用于指定 Flink runtime 如何执行这个函数。目前,只支持 JAVA, SCALA 和 PYTHON,且函数的默认语言为 JAVA。