CREATE TABLE [USING]
适用于: Databricks SQL Databricks Runtime
可以使用数据源定义托管表或外部表。
语法
{ { [CREATE OR] REPLACE TABLE | CREATE [EXTERNAL] TABLE [ IF NOT EXISTS ] }
table_name
[ table_specification ]
[ USING data_source ]
[ table_clauses ]
[ AS query ] }
table_specification
( { column_identifier column_type [ column_properties ] } [, ...]
[ , table_constraint ] [...] )
column_properties
{ NOT NULL |
GENERATED ALWAYS AS ( expr ) |
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( [ START WITH start ] [ INCREMENT BY step ] ) ] |
DEFAULT default_expression |
COMMENT column_comment |
column_constraint |
MASK clause } [ ... ]
table_clauses
{ OPTIONS clause |
PARTITIONED BY clause |
CLUSTER BY clause |
clustered_by_clause |
LOCATION path [ WITH ( CREDENTIAL credential_name ) ] |
COMMENT table_comment |
TBLPROPERTIES clause |
WITH { ROW FILTER clause } } [...]
clustered_by_clause
{ CLUSTERED BY ( cluster_column [, ...] )
[ SORTED BY ( { sort_column [ ASC | DESC ] } [, ...] ) ]
INTO num_buckets BUCKETS }
parameters
REPLACE
如果指定了该参数,则会替换已存在的表及其内容。 只有 Delta Lake 表支持此子句。
REPLACE
保留表历史记录。注意
Azure Databricks 强烈建议使用
REPLACE
,而不是删除再重新创建 Delta Lake 表。EXTERNAL
如果已指定,则会创建一个外部表。 创建外部表时,还必须提供
LOCATION
子句。 删除外部表时,不会删除位于LOCATION
处的文件。IF NOT EXISTS
如果指定了该参数,并且已存在名称相同的表,则会忽略该语句。
IF NOT EXISTS
无法与REPLACE
共存,这意味着不允许使用CREATE OR REPLACE TABLE IF NOT EXISTS
。-
要创建的表的名称。 名称不得包含 时态规范或选项规范。 如果未限定该名称,则会在当前架构中创建该表。
hive_metastore
中创建的表只能包含字母数字 ASCII 字符和下划线 (INVALID_SCHEMA_OR_RELATION_NAME)。 table_specification
此可选子句定义列的列表、列的类型、属性、说明和列约束。
如果未在表架构中定义列,则必须指定
AS query
或LOCATION
。-
列的唯一名称。
没有列映射属性 (
'delta.columnMapping.mode' = 'name'
) 的 Delta Lake 表的列标识符不得包含空格或以下字符:, ; { } ( ) \n \t =
。AVRO
表的列标识符必须以下划线 (_
) 或 Unicode 字母(包括非 ASCII 字母)开头,后跟 Unicode 字母、数字和下划线的组合。 -
指定列的数据类型。 并非所有数据源都支持 Azure Databricks 支持的所有数据类型。
NOT NULL
如果指定了该参数,则列不会接受
NULL
值。 只有 Delta Lake 表支持此子句。GENERATED ALWAYS AS ( expr )
指定此子句后,此列的值取决于
expr
。expr
可能包含文本、表中的列标识符以及内置的确定性 SQL 函数或运算符,但以下内容除外:此外,
expr
不能包含任何expr
。GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( [ START WITH start ] [ INCREMENT BY step ] ) ]
适用于: Databricks SQL Databricks Runtime 10.4 LTS 及更高版本
定义标识列。 如果你写入表但没有为标识列提供值,它将自动分配一个唯一且统计上递增的值(如果
step
为负数则递减)。 只有 Delta Lake 表支持此子句。 此子句只能用于具有 BIGINT 数据类型的列。自动分配的值以
start
开头并以step
为增量。 分配的值是唯一的,但不保证是连续的。 这两个参数都是可选的,默认值为 1。step
不能为0
。如果自动分配的值超出标识列类型的范围,则查询将失败。
使用
ALWAYS
时,不能为标识列提供自己的值。不支持以下操作:
PARTITIONED BY
是标识列UPDATE
是标识列
注意
在 Delta 表上声明标识列会禁用并发事务。 仅在不需要对目标表进行并发写入的用例中使用标识列。
DEFAULT default_expression
适用于: Databricks SQL Databricks Runtime 11.3 LTS 及更高版本
为列定义一个
DEFAULT
值,当未指定该列时,将在INSERT
、UPDATE
和MERGE ... INSERT
上使用该值。如果未指定默认值,则
DEFAULT NULL
应用于可为空的列。default_expression
可以由字面量和内置 SQL 函数或运算符组成,但以下情况除外:此外,
default_expression
不能包含任何default_expression
。CSV
、JSON
、PARQUET
和ORC
源支持DEFAULT
。COMMENT column_comment
用于描述列的字符串字面量。
-
向 Delta Lake 表中的列添加主键或外键约束。
hive_metastore
目录中的表不支持约束。若要向 Delta Lake 表添加 CHECK 约束,请使用 ALTER TABLE。
-
适用于: Databricks SQL Databricks Runtime 12.2 LTS 及更高版本 仅 Unity Catalog
重要
此功能目前以公共预览版提供。
添加列掩码函数以对敏感数据进行匿名化处理。 该列的所有后续查询都会收到对该列评估该函数的结果,而不是该列的原始值。 这对于细粒度的访问控制目的非常有用,在这种情况下,该函数可以检查调用用户的身份或组成员身份,以便决定是否编辑该值。
-
向 Delta Lake 表添加信息性主键或信息性外键约束。
hive_metastore
目录中的表不支持键约束。若要向 Delta Lake 表添加 CHECK 约束,请使用 ALTER TABLE。
-
USING data_source
data_source
可以是文件格式,也可以是联合 JDBC 数据源。文件格式必须是以下之一:
AVRO
BINARYFILE
CSV
DELTA
JSON
ORC
PARQUET
TEXT
对于除
DELTA
之外的任何文件格式,还必须指定LOCATION
,除非表目录为hive_metastore
。支持以下联合 JDBC 源:
POSTGRESQL
SQLSERVER
MYSQL
BIGQUERY
NETSUITE
ORACLE
REDSHIFT
SNOWFLAKE
SQLDW
SYNAPSE
SALESFORCE
SALESFORCE_DATA_CLOUD
TERADATA
WORKDAY_RAAS
MONGODB
指定联合 JDBC 源时,还必须指定带有必要连接信息的
OPTIONS
子句。 有关查询联合数据源的详细信息,请参阅使用 JDBC 查询数据库。Databricks Runtime 支持用于表的以下附加文件格式:
JDBC
LIBSVM
org.apache.spark.sql.sources.DataSourceRegister
的自定义实现的完全限定的类名。
如果省略
USING
,则默认值为DELTA
。以下内容适用于:Databricks Runtime
支持
HIVE
在 Databricks Runtime 中创建 Hive SerDe 表。 你可以使用OPTIONS
子句指定 Hive 特定的file_format
和row_format
,这是不区分大小写的字符串映射。option_keys
为:FILEFORMAT
INPUTFORMAT
OUTPUTFORMAT
SERDE
FIELDDELIM
ESCAPEDELIM
MAPKEYDELIM
LINEDELIM
table_clauses
可选择指定新表的位置、分区、群集、选项、注释和用户定义的属性。 每个子子句只能指定一次。
-
用于按列子集对表进行分区的可选子句。
注意
如果未定义 Delta 表,则分区列会放在表的末尾,即使它们在列规范中早先被定义。 请考虑对 Delta 表使用
CLUSTER BY
,而不是PARTITIONED BY
。 -
适用于: Databricks SQL Databricks Runtime 13.3 及更高版本
一个可选子句,用于按列的子集对 Delta 表进行聚类。 若要对其他表进行聚类,请使用
clustered_by_clause
。Delta Lake 液态聚类不能与
PARTITIONED BY
合并。 clustered_by_clause
可选择使用列子集将表或每个分区聚集到固定数量的哈希桶中。
Delta Lake 表不支持群集功能。
CLUSTERED BY
指定列集,用于聚集每个分区,如果未指定任何分区,则用于聚集表。
-
引用表中
column_identifier
的标识符。 如果指定多列,则不能有重复项。 由于群集在分区级别进行操作,因此不能将分区列同时命名为群集列。
-
SORTED BY
可选择保留桶中的行的排序顺序。
sort_column
用于对桶进行排序的列。 该列不能为分区列。 排序列必须是唯一的。
ASC 或 DESC
可选择指定是按升序 (
ASC
) 还是降序 (DESC
) 对sort_column
进行排序。 默认值为ASC
。
INTO num_buckets BUCKETS
一个整数文本,用于指定将每个分区(或表 [如果未指定任何分区])划分到的 Bucket 数目。
LOCATION path [ WITH ( CREDENTIAL credential_name ) ]
用于存储表数据的可选目录路径,可以是分布式存储上的一个路径。
path
必须是字符串字面量。 如果未指定位置,则会将表视为managed table
,并且 Azure Databricks 会创建默认表位置。指定一个位置会使表成为外部表。
对于未驻留在
hive_metastore
目录中的表(表path
),必须由外部位置保护,除非指定了有效的存储凭据。不能在与托管表的位置重叠的位置创建外部表。
对于 Delta Lake 表,如果存在数据,则表配置继承自
LOCATION
。 因此,如果为 Delta Lake 表指定了任何TBLPROPERTIES
、table_specification
或PARTITIONED BY
子句,则它们必须与 Delta Lake 位置数据完全匹配。-
设置或重置一个或多个用户定义的表选项。
COMMENT table_comment
用于描述表的字符串字面量。
-
可以选择设置一个或多个用户定义的属性。
WITH ROW FILTER 子句
适用于: Databricks SQL Databricks Runtime 12.2 LTS 及更高版本 仅 Unity Catalog
向表中添加行筛选器函数。 该表中的所有后续查询都将收到函数计算结果为布尔值 TRUE 的行的子集。 这对于细粒度的访问控制目的非常有用,在这种情况下,该函数可以检查调用用户的身份或组成员身份,以决定是否筛选特定行。
-
AS 查询
此可选子句使用
query
中的数据来填充表。 指定query
时,不能同时指定table_specification
。 表架构派生自查询。请注意,Azure Databricks 会用输入查询的数据覆盖基础数据源,确保创建的表包含与输入查询完全相同的数据。
示例
-- Creates a Delta table
> CREATE TABLE student (id INT, name STRING, age INT);
-- Use data from another table
> CREATE TABLE student_copy AS SELECT * FROM student;
-- Creates a CSV table from an external directory
> CREATE TABLE student USING CSV LOCATION '/path/to/csv_files';
-- Specify table comment and properties
> CREATE TABLE student (id INT, name STRING, age INT)
COMMENT 'this is a comment'
TBLPROPERTIES ('foo'='bar');
-- Specify table comment and properties with different clauses order
> CREATE TABLE student (id INT, name STRING, age INT)
TBLPROPERTIES ('foo'='bar')
COMMENT 'this is a comment';
-- Create partitioned table
> CREATE TABLE student (id INT, name STRING, age INT)
PARTITIONED BY (age);
-- Create a table with a generated column
> CREATE TABLE rectangles(a INT, b INT,
area INT GENERATED ALWAYS AS (a * b));
-- Create an external table connected to Oracle
> CREATE TABLE IF NOT EXISTS ora_tab
USING ORACLE
OPTIONS (
url '<jdbc-url>',
dbtable '<table-name>',
user '<username>',
password '<password>'
);
> SELECT * FROM ora_tab;