CREATE TABLE - Amazon Redshift

CREATE TABLE

在当前数据库中创建一个新表。您可以定义一个列的列表,用于存储不同类型的数据。此表的所有者为 CREATE TABLE 命令的发布者。

所需的权限

以下是 CREATE TABLE 所需的权限:

  • Superuser

  • 具有 CREATE TABLE 权限的用户

语法

CREATE [ [LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] table_name ( { column_name data_type [column_attributes] [ column_constraints ] | table_constraints | LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ] } [, ... ] ) [ BACKUP { YES | NO } ] [table_attributes] where column_attributes are: [ DEFAULT default_expr ] [ IDENTITY ( seed, step ) ] [ GENERATED BY DEFAULT AS IDENTITY ( seed, step ) ] [ ENCODE encoding ] [ DISTKEY ] [ SORTKEY ] [ COLLATE CASE_SENSITIVE | COLLATE CASE_INSENSITIVE ] and column_constraints are: [ { NOT NULL | NULL } ] [ { UNIQUE | PRIMARY KEY } ] [ REFERENCES reftable [ ( refcolumn ) ] ] and table_constraints are: [ UNIQUE ( column_name [, ... ] ) ] [ PRIMARY KEY ( column_name [, ... ] ) ] [ FOREIGN KEY (column_name [, ... ] ) REFERENCES reftable [ ( refcolumn ) ] and table_attributes are: [ DISTSTYLE { AUTO | EVEN | KEY | ALL } ] [ DISTKEY ( column_name ) ] [ [COMPOUND | INTERLEAVED ] SORTKEY ( column_name [,...]) | [ SORTKEY AUTO ] ] [ ENCODE AUTO ]

参数

LOCAL

可选。虽然语句中接受此关键词,但它在 Amazon Redshift 中没有任何作用。

TEMPORARY | TEMP

一个关键字,可创建仅在当前会话中可见的临时表。在从中创建表的会话结束时,将自动删除此表。临时表可具有与永久表相同的名称。在特定于会话的单独 schema 中创建临时表。(您无法为此 schema 指定名称。) 此临时架构将成为搜索路径中的第一个架构,因此临时表优先于永久表,除非您使用架构名称来限定表名以访问永久表。有关 schema 和优先顺序的更多信息,请参阅 search_path

注意

默认情况下,数据库用户有权通过其在 PUBLIC 组中自动获得的成员资格来创建临时表。要拒绝向用户授予此权限,可从 PUBLIC 组撤消 TEMP 权限,然后仅将 TEMP 权限显式授予特定用户或用户组。

IF NOT EXISTS

这个子句指示,如果指定的表已存在,命令应不进行任何更改并返回一条指示表存在的消息,而不是出错停止。请注意,现有表可能与已创建的表完全不同;仅比较表名。

此子句在编写脚本时很有用,可使脚本在 CREATE TABLE 尝试创建已存在的表时不会失败。

table_name

要创建的表的名称。

重要

如果指定以“#”开始的表名,表会创建为临时表。以下是示例:

create table #newtable (id int);

您还可使用“#”引用该表。例如:

select * from #newtable;

表名称的最大长度为 127 个字节;更长的名称将被截断为 127 个字节。您可以使用 UTF-8 多字节字符,每个字符最多为四个字节。Amazon Redshift 按节点类型对每个集群强制实施表数量的配额,包括用户定义的临时表以及查询处理或系统维护期间由 Amazon Redshift 创建的临时表。也可使用数据库名称和 schema 名称来限定表名称。在下面的示例中,tickit 是数据库名称,public 是 schema 名称,而 test 是表名称。

create table tickit.public.test (c1 int);

如果数据库或 schema 不存在,则不会创建表,并且语句将返回错误。您无法在系统数据库 template0template1padb_harvestsys:internal 中创建表或视图。

如果提供 schema 名称,则在该 schema 中创建新表(假定创建者有权访问 schema)。表名称必须是该 schema 中的唯一名称。如果未指定 schema,则可使用当前数据库 schema 创建表。如果您创建的是临时表,则无法指定 schema 名称,因为特定 schema 中存在临时表。

同一个数据库中可同时存在多个同名的临时表,前提是这些临时表是在单独的会话中创建的,因为这些表将分配给不同的 schema。有关有效名称的更多信息,请参阅名称和标识符

column_name

要在新表中创建的列的名称。列名称的最大长度为 127 个字节;更长的名称将被截断为 127 个字节。您可以使用 UTF-8 多字节字符,每个字符最多为四个字节。可在单个表中定义的列的最大数目为 1,600。有关有效名称的更多信息,请参阅名称和标识符

注意

如果您创建的是“宽表”,请注意,在加载和查询处理期间,不要让列列表超出中间结果的行宽度边界。有关更多信息,请参阅 使用说明

data_type

要创建的列的数据类型。对于 CHAR 和 VARCHAR 列,您可以使用 MAX 关键字而不是声明最大长度。MAX 将最大长度设置为 4096 字节(对于 CHAR)或 65535 字节(对于 VARCHAR)。GEOMETRY 对象的最大大小为 1048447 字节。

有关 Amazon Redshift 支持的数据类型的信息,请参阅数据类型

DEFAULT default_expr

一个为列分配默认数据值的子句。default_expr 的数据类型必须匹配列的数据类型。DEFAULT 值必须是无变量的表达式。不允许子查询、对当前表中其他列的交叉引用和用户定义的函数。

default_expr 表达式可用于未为列指定值的任何 INSERT 操作。如果未指定默认值,则列的默认值为 null。

如果具有定义的列列表的 COPY 操作忽略具有 DEFAULT 值的列,则 COPY 命令将插入 default_expr 的值。

IDENTITY(seed, step)

一个指定列为 IDENTITY 列的子句。IDENTITY 列包含唯一的自动生成的值。IDENTITY 列的数据类型必须为 INT 或 BIGINT。

使用 INSERTINSERT INTO [tablename] VALUES() 语句添加行时,这些值以指定为 seed 的值开始,并按照指定为 step 的数字递增。

使用 INSERT INTO [tablename] SELECT * FROMCOPY 语句加载表时,数据将并行加载并分发到节点切片。为确保身份值唯一,Amazon Redshift 在创建身份值时跳过多个值。身份值是唯一的,但顺序可能与源文件中的顺序不匹配。

GENERATED BY DEFAULT AS IDENTITY (seed, step)

指定该列为默认 IDENTITY 列并使您可以自动为该列分配唯一值的子句。IDENTITY 列的数据类型必须为 INT 或 BIGINT。添加不含值的行时,这些值以指定为 seed 的值开始,并按照指定为 step 的数字递增。有关如何生成值的信息,请参阅IDENTITY

此外,在 INSERT、UPDATE 或 COPY 期间,您可以提供没有 EXPLICIT_IDS 的值。Amazon Redshift 会使用该值插入到身份列,而不是使用系统生成的值。该值可以是重复值、小于 seed 的值或介于 step 值之间的值。Amazon Redshift 不检查列中值的唯一性。提供一个值不会影响下一个系统生成的值。

注意

如果您需要在列中保持唯一性,请勿添加重复值。而是添加小于 seed 或介于 step 值之间的唯一值。

记住与默认身份列有关的以下信息:

  • 默认身份列为 NOT NULL。不能插入 NULL。

  • 要将生成的值插入默认身份列,请使用关键字 DEFAULT

    INSERT INTO tablename (identity-column-name) VALUES (DEFAULT);
  • 覆盖默认身份列的值不会影响下一个生成的值。

  • 您无法使用 ALTER TABLE ADD COLUMN 语句添加默认身份列。

  • 您可以使用 ALTER TABLE APPEND 语句附加默认身份列。

ENCODE encoding

列的压缩编码。ENCODE AUTO 是表的默认设置。Amazon Redshift 会自动管理表中所有列的压缩编码。如果为表中的任何列指定压缩编码,则表不再设置为 ENCODE AUTO。Amazon Redshift 不再自动管理表中所有列的压缩编码。您可以为表指定 ENCODE AUTO 选项,以使 Amazon Redshift 能够自动管理表中所有列的压缩编码。

Amazon Redshift 会自动为您未指定压缩编码的列分配初始压缩编码,如下所示:

  • 默认情况下,会为临时表中的所有列分配 RAW 压缩。

  • 为定义为排序键的列分配 RAW 压缩。

  • 定义为 BOOLEAN、REAL、DOUBLE PRECISION、GEOMETRY 或 GEOGRAPHY 数据类型的列分配了 RAW 压缩。

  • 定义为 SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ 的列分配了 AZ64 压缩。

  • 定义为 CHAR、VARCHAR 或 VARBYTE 的列分配了 LZO 压缩。

注意

如果您不希望压缩某个列,请显式指定 RAW 编码。

支持以下compression encodings

  • AZ64

  • BYTEDICT

  • DELTA

  • DELTA32K

  • LZO

  • MOSTLY8

  • MOSTLY16

  • MOSTLY32

  • RAW(无压缩)

  • RUNLENGTH

  • TEXT255

  • TEXT32K

  • ZSTD

DISTKEY

一个指定列为表的分配键的关键字。一个表中只能有一个列可成为分配键。可在列名后使用 DISTKEY 关键字,也可使用 DISTKEY (column_name) 语法将该关键字用作表定义的一部分。每种方法的效果相同。有关更多信息,请参阅本主题后面的 DISTSTYLE 参数。

分配键列的数据类型可以为:BOOLEAN、REAL、DOUBLE PRECISION、SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ、CHAR 或 VARCHAR。

SORTKEY

一个指定列为表的排序键的关键字。在数据加载到表中后,将按指定为排序键的一个或多个列对数据进行排序。可在列名后使用 SORTKEY 关键字来指定单列排序键,也可使用 SORTKEY (column_name [, ...]) 语法将一个或多个列指定为表的排序键列。仅使用此语法创建复合排序键。

您最多可以为每个表定义 400 个 SORTKEY 列。

排序键列的数据类型可以为:BOOLEAN、REAL、DOUBLE PRECISION、SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ、CHAR 或 VARCHAR。

COLLATE CASE_SENSITIVE | COLLATE CASE_INSENSITIVE

指定列中的字符串搜索或比较是 CASE_SENSITIVE 还是 CASE_INSENSITIVE 的子句。默认值与数据库的当前区分大小写的配置相同。

要查找数据库排序规则信息,请使用以下命令:

SELECT db_collation(); db_collation ---------------- case_sensitive (1 row)
NOT NULL | NULL

NOT NULL 指定列中不允许包含 null 值。NULL(默认值)指定列接受 null 值。默认情况下,将 IDENTITY 列声明为 NOT NULL。

UNIQUE

一个指定列只能包含唯一值的关键字。唯一表约束的行为与列约束的行为相同,但前者能够跨多个列。要定义唯一表约束,请使用 UNIQUE ( column_name [, ... ] ) 语法。

重要

唯一约束是信息性的,而不由系统强制实施。

PRIMARY KEY

一个指定列为表的主键的关键字。通过使用列定义,只能将一个列定义为主键。要使用多列主键定义表约束,请使用 PRIMARY KEY ( column_name [, ... ] ) 语法。

通过将一个列标识为主键,可提供有关 schema 设计的元数据。主键意味着其他表可将此列集用作行的唯一标识符。可以为一个表指定一个主键,作为列约束或表约束。主键约束指定的列集应不同于为同一表定义的任何唯一约束指定的其他列集。

PRIMARY KEY 列也定义为 NOT NULL。

重要

主键约束仅为信息性的。这些约束不由系统强制实施,而是由计划程序使用。

References reftable [ ( refcolumn ) ]

一个指定外键约束的子句,该外键约束暗示列包含的值必须与被引用表的某个行的被引用列中的值匹配。被引用列应为引用的表中的唯一或主键约束的列。

重要

外键约束仅为信息性的。这些约束不由系统强制实施,而是由计划程序使用。

LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ]

一个指定现有表的子句,新表自动从该表中复制列名、数据类型和 NOT NULL 约束。新表和父表是分离的,对父表所做的所有更改都不适用于新表。仅在指定 INCLUDING DEFAULTS 的情况下复制已复制列定义的默认表达式。默认行为是排除默认表达式,以便新表的所有列包含 null 默认值。

使用 LIKE 选项创建的表不继承主键约束和外键约束。分配样式、排序键、BACKUP 和 NULL 属性由 LIKE 表继承,但您无法在 CREATE TABLE ... LIKE 语句中明确设置这些 属性。

BACKUP { YES | NO }

一个子句,指定表是否应包含在自动和手动集群快照中。

对于不会包含关键数据的表(如暂存表),请指定 BACKUP NO 以节省在创建快照并从快照还原时的处理时间,从而减小在 Amazon Simple Storage Service 上占用的存储空间。BACKUP NO 设置不会影响数据自动复制到集群内的其他节点,因此当发生节点故障时,指定了 BACKUP NO 的表将被还原。默认值为 BACKUP YES。

DISTSTYLE { AUTO | EVEN | KEY | ALL }

定义整个表的数据分配样式的关键词。Amazon Redshift 会根据为表指定的分配样式将表行分配给计算节点。默认值为 AUTO。

为表选择的分配样式将影响数据库的整体性能。有关更多信息,请参阅 用于优化查询的数据分配。可能的分配样式如下:

  • AUTO:Amazon Redshift 可基于表数据指定最佳分配方式。例如,如果指定 AUTO 分配方式,Amazon Redshift 最初向小型表指定的是 ALL 分配方式。当表变大时,Amazon Redshift 可能会将分配方式更改为 KEY,选择主键(或复合主键的列)作为 DISTKEY。如果表变大且没有任何一列适合用作 DISTKEY,Amazon Redshift 会将分配方式更改为 EVEN。分配方式的更改在后台进行,对用户查询的影响极小。

    要查看应用于表的分配方式,请查询 PG_CLASS 系统目录表。有关更多信息,请参阅 查看分配方式

  • EVEN:表中的数据在轮询分配中跨集群中的节点均匀分布。行 ID 用来确定分配,并且为每个节点分配的行数大致相同。

  • KEY:按 DISTKEY 列中的值分配数据。在您将联接表的联接列设置为分配键时,来自这两个表的联接行将在计算节点上并置。在并置数据时,优化程序可更高效地执行联接。如果您指定 DISTSTYLE KEY,则必须为表指定 DISTKEY 列或者将此列指定为列定义的一部分。有关更多信息,请参阅本主题前面的 DISTKEY 参数。

  • ALL:向每个节点分配整个表的副本。此分配样式可确保任何联接所需的所有行在每个节点上都可用,但这将使存储要求成倍提高,并且会增加表的加载和维护次数。将 ALL 分配样式用于 KEY 分配不适用的部分维度表时会缩短执行时间,但必须针对维护成本来权衡性能改进。

DISTKEY ( column_name )

一个约束,指定要用作表的分配键的列。可在列名后使用 DISTKEY 关键字,也可使用 DISTKEY (column_name) 语法将该关键字用作表定义的一部分。每种方法的效果相同。有关更多信息,请参阅本主题前面的 DISTSTYLE 参数。

[COMPOUND | INTERLEAVED ] SORTKEY ( column_name [,...]) | [ SORTKEY AUTO ]

为表指定一个或多个排序键。在数据加载到表中后,将按指定为排序键的列对数据进行排序。可在列名后使用 SORTKEY 关键字来指定单列排序键,也可使用 SORTKEY (column_name [ , ... ] ) 语法将一个或多个列指定为表的排序键列。

您可以选择指定 COMPOUND 或 INTERLEAVED 排序样式。如果使用列指定 SORTKEY,则默认值为 COMPOUND。有关更多信息,请参阅 排序键

如果您不指定任何排序键选项,则默认设置为 AUTO。

最多可以为每个表定义 400 个 COMPOUND SORTKEY 列或 8 个 INTERLEAVED SORTKEY 列。

AUTO

指定 Amazon Redshift 会基于表数据分配最佳排序键。例如,如果指定了 AUTO 排序键,Amazon Redshift 最初不会为表分配排序键。如果 Amazon Redshift 确定排序键将提高查询的性能,那么 Amazon Redshift 可能会更改您的表的排序键。表的实际排序通过自动表排序完成。有关更多信息,请参阅 自动表排序

Amazon Redshift 不会修改具有现有排序键或分配键的表。一个例外情况是,如果表具有从未在 JOIN 中使用过的分配键,则可能会在 Amazon Redshift 确定有更好的键时更改键。

要查看表的排序键,请查询 SVV_TABLE_INFO 系统目录视图。有关更多信息,请参阅 SVV_TABLE_INFO。要查看 Amazon Redshift Advisor 对表的建议,请查询 SVV_ALTER_TABLE_RECOMMENDATIONS 系统目录视图。有关更多信息,请参阅 SVV_ALTER_TABLE_RECOMMENDATIONS。要查看 Amazon Redshift 所采取的操作,请查询 SVL_AUTO_WORKER_ACTION 系统目录视图。有关更多信息,请参阅 SVL_AUTO_WORKER_ACTION

COMPOUND

指定使用由所有列出的列构成的复合键按这些列的列出顺序对数据进行排序。当查询根据排序列的顺序扫描行时,复合排序键最有用。当查询依赖辅助排序列时,使用复合键进行排序所带来的性能好处会减少。您最多可以为每个表定义 400 个 COMPOUND SORTKEY 列。

INTERLEAVED

指定使用交错排序键对数据进行排序。可以为一个交错排序键最多指定 8 个列。

交错排序为排序键中的每个列或列子集提供了相同的权重,以便查询不会依赖列在排序键中的顺序。当查询使用一个或多个辅助排序列时,交错排序会大大提高查询性能。交错排序产生的数据加载和 vacuum 操作的开销成本较低。

重要

不要在具有单调递增属性的列(例如,身份列、日期或时间戳)上使用交错排序键。

ENCODE AUTO

使 Amazon Redshift 能够自动调整表中所有列的编码类型,以优化查询性能。ENCODE AUTO 会保留您在创建表时指定的初始编码类型。然后,如果 Amazon Redshift 确定新的编码类型可以提高查询性能,则 Amazon Redshift 可以更改表列的编码类型。如果不在表中的任何列上指定编码类型,则 ENCODE AUTO 是默认设置。

UNIQUE ( column_name [,...] )

一个约束,指定包含一个或多个表列的组只能包含唯一值。唯一表约束的行为与列约束的行为相同,但前者能够跨多个列。在唯一约束的上下文中,null 值不被视为相同。每个唯一表约束指定的列集必须不同于由为表定义的任何其他唯一键约束或主键约束指定的列集。

重要

唯一约束是信息性的,而不由系统强制实施。

PRIMARY KEY ( column_name [,...] )

一个约束,指定表的一个列或大量列只能包含唯一(不重复)的非 null 值。通过将一个列集标识为主键,也会提供有关 schema 设计的元数据。主键意味着其他表可将此列集用作行的唯一标识符。可以为一个表指定一个主键,作为单个列约束或表约束。主键约束指定的列集应不同于为同一表定义的任何唯一约束指定的其他列集。

重要

主键约束仅为信息性的。这些约束不由系统强制实施,而是由计划程序使用。

FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn ) ]

一个指定外键约束的约束,该约束要求新表的一个或多个列只能包含与被引用表的某个行的一个或多个被引用列中的值匹配的值。如果忽略 refcolumn,则使用 reftable 的主键。被引用列必须为被引用表中的唯一或主键约束的列。

重要

外键约束仅为信息性的。这些约束不由系统强制实施,而是由计划程序使用。

使用说明

唯一键、主键和外键约束仅供参考;在您填充表时,Amazon Redshift 并不强制实施它们。例如,如果您将数据插入到具有依赖关系的表中,即使插入操作违反了约束,插入也会成功。但是,主键和外键用作规划提示,如果您应用程序中的 ETL 处理或其他一些处理强制其完整性,则应声明它们。有关如何删除具有依赖关系的表的信息,请参阅 DROP TABLE

限制和配额

创建表时,请考虑以下限制。

  • 集群中按节点类型的最大表数有限制。有关更多信息,请参阅《Amazon Redshift 管理指南》中的限制

  • 表名的最大字符数为 127。

  • 可在单个表中定义的列的最大数目为 1,600。

  • 可在单个表中定义的 SORTKEY 列的最大数目为 400。

列级设置和表级设置摘要

可在列级或表级设置若干属性和设置。在某些情况下,在列级或表级设置属性或约束的效果相同。在其他情况下,它们会产生不同的结果。

下面的列表汇总了列级和表级设置:

DISTKEY

无论是在列级设置还是在表级设置,效果是相同的。

如果在列级或表级设置 DISTKEY,则 DISTSTYLE 必须设置为 KEY 或者根本不设置 DISTSTYLE。只能在表级设置 DISTSTYLE。

SORTKEY

如果在列级进行设置,则 SORTKEY 必须为单个列。如果在表级设置 SORTKEY,则一个或多个列可构成复合或交错复合排序键。

COLLATE CASE_SENSITIVE | COLLATE CASE_INSENSITIVE

Amazon Redshift 不支持更改列的区分大小写配置。将新列附加到表中时,Amazon Redshift 会使用默认值区分大小写。在附加新列时,Amazon Redshift 不支持 COLLATE 关键字。

有关如何使用数据库排序规则创建数据库的信息,请参阅CREATE DATABASE

有关 COLLATE 函数的信息,请参阅COLLATE 函数

UNIQUE

在列级别,可将一个或多个键设置为 UNIQUE;UNIQUE 约束分别应用于每个列。如果在表级设置 UNIQUE,则一个或多个列可构成复合 UNIQUE 约束。

PRIMARY KEY

如果在列级进行设置,则 PRIMARY KEY 必须为单个列。如果在表级设置 PRIMARY KEY,则一个或多个列可构成复合主键。

FOREIGN KEY

无论是在列级设置还是在表级设置 FOREIGN KEY,效果是相同的。在列级别,语法为 REFERENCES reftable [ ( refcolumn )]。

分配传入数据

如果传入数据的哈希分配方案与目标表的哈希分配方案匹配,则在加载数据时,没有实际必要的数据物理分配。例如,如果为新表设置分配键并从相同键列上分配的另一个表中插入数据,则使用相同的节点和切片就地加载数据。不过,如果源表和目标表都设置为 EVEN 分配,则数据将重新分配到目标表。

宽表

您也许能够创建很宽的表,但无法对表执行查询处理,例如 INSERT 或 SELECT 语句。具有宽度固定的列(例如 CHAR)的表的最大宽度为 64KB - 1(即 65535 字节)。如果表包含 VARCHAR 列,则表可以具有更大的声明宽度,而不会返回错误,因为 VARCHARS 列不会将其完全声明的宽度计入计算出的查询处理限制。针对 VARCHAR 列的有效查询处理限制将因大量因素而异。

如果表对于插入或选择操作来说太宽,您将收到以下错误。

ERROR: 8001 DETAIL: The combined length of columns processed in the SQL statement exceeded the query-processing limit of 65535 characters (pid:7627)

示例

有关说明 CREATE TABLE 命令用法的示例,请参阅示例 主题。