View a markdown version of this page

CREATE TABLE - Amazon Aurora DSQL

CREATE TABLE

CREATE TABLE 定义一个新表。

支持的语法

CREATE TABLE [ IF NOT EXISTS ] table_name ( [ { column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option ... ] } [, ... ] ] ) where column_constraint is: [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY ( sequence_options ) | UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] and table_constraint is: [ CONSTRAINT constraint_name ] { CHECK ( expression ) | UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters | PRIMARY KEY ( column_name [, ... ] ) index_parameters | FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] and referential_action in a FOREIGN KEY/REFERENCES constraint is: { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } and like_option is: { INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | ALL } index_parameters in UNIQUE and PRIMARY KEY constraints are: [ INCLUDE ( column_name [, ... ] ) ]

标识列

注意

使用标识列时,应谨慎考虑缓存值。有关更多信息,请参阅 CREATE SEQUENCE 页面上的“重要提示”标注。

有关如何根据工作负载模式以最佳方式使用标识列的指导,请参阅使用序列和标识列。

GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY ( sequence_options ) 子句将列创建为标识列。它将附加一个隐式序列,在新插入的行中,该列将自动具有序列中分配给它的值。这样的列隐式为 NOT NULL。

子句 ALWAYS 和 BY DEFAULT 决定了在 INSERT 和 UPDATE 命令中如何显式处理用户指定的值。

在 INSERT 命令中,如果选择了 ALWAYS,则只有在 INSERT 语句指定 OVERRIDING SYSTEM VALUE 时才接受用户指定的值。如果选择了 BY DEFAULT,则优先使用用户指定的值。

在 UPDATE 命令中,如果选择 ALWAYS,则将列更新为除 DEFAULT 以外的任何值都将遭到拒绝。如果选择 BY DEFAULT,则可以正常更新该列。(UPDATE 命令没有 OVERRIDING 子句。)

sequence_options 子句可用于覆盖序列的参数。可用的选项包括为 CREATE SEQUENCE 显示的选项,另加 SEQUENCE NAME name。如果没有 SEQUENCE NAME,则系统会为序列选择一个未使用的名称。

存储模式

可选的 STORAGE 子句可设置列的存储模式。使用这些选项可控制可变长度数据类型(例如 JSON、JSONB、TEXT、VARCHAR 和 BPCHAR)的压缩行为。

当某些数据类型超过特定大小时,Amazon Aurora DSQL 会对其进行压缩。要禁用此行为,请使用 PLAIN 或 EXTERNAL 选项。

PLAIN

Aurora DSQL 以内联方式存储数据,且不进行压缩。这是适用于固定长度数据类型(例如 integer)的唯一选项。使用此选项可禁止对某些可变长度类型进行压缩。

MAIN | EXTENDED | DEFAULT

如果基础数据类型支持压缩,则 MAIN 和 EXTENDED 允许对列进行可选压缩。DEFAULT 可将存储模式设置为列数据类型的默认模式。

EXTERNAL

Aurora DSQL 目前不支持 TOAST 表,但 EXTERNAL 会对支持压缩的数据类型禁用压缩。

外键约束

REFERENCES 和 FOREIGN KEY 子句用于指定外键约束,该约束要求新表中的一个或多个列只能包含与被引用表某行的被引用列中的值相匹配的值。如果省略 refcolumn 列表,则 Aurora DSQL 将使用 reftable 的主键。否则,refcolumn 列表必须引用不可延迟的唯一约束或主键约束的列。

Aurora DSQL 使用给定的匹配类型将已插入引用列的值与被引用表和被引用列的值进行匹配。有两种受支持的匹配类型:MATCH FULL 和 MATCH SIMPLE(默认值)。

您可将外键定义为列约束或表约束:

  • 列约束(REFERENCES):对于单列外键,在列数据类型后使用 REFERENCES。

  • 表约束(FOREIGN KEY):对于单列或多列外键,使用 FOREIGN KEY (...) REFERENCES ...。

引用操作

在您更改被引用列中的数据时,Aurora DSQL 会对引用表的列中的数据执行相应操作。ON DELETE 子句用于指定当事务删除被引用表中的被引用行时要执行的操作。同样地,ON UPDATE 子句用于指定当事务将被引用列更新为新值时要执行的操作。如果事务更新了行但未更改被引用列,Aurora DSQL 将不执行任何操作。

Aurora DSQL 支持以下引用操作:

NO ACTION(默认)

如果删除或更新操作会引发外键约束冲突,则会产生错误。如果约束是可延迟约束,则只要在约束检查时仍存在任何引用行,Aurora DSQL 就会产生此错误。这是默认操作。

RESTRICT

如果要删除或更新的行与引用表中的某个行匹配,则会产生错误。即使操作后的状态不会引发外键约束冲突,此操作也会被阻止。特别是,它可防止将被引用行更新为值不相同但比较结果相等的值。与 NO ACTION 不同,RESTRICT 检查不可延迟。

级联操作计入事务修改行数上限

在更新或删除被引用行时,CASCADE、SET NULL 和 SET DEFAULT 操作会自动修改引用表中的行。Aurora DSQL 事务行数限制适用于这些操作,如果使用不当,可能导致意外失败。对于子行基数不受限或不可预测的外键关系,建议优先使用 NO ACTION 或 RESTRICT。有关更多信息,请参阅 Aurora DSQL 中的数据库限制。

CASCADE

删除所有引用已删除行的行,或将引用列的值分别更新为被引用列的新值。

SET NULL [ ( column_name [, ... ] ) ]

将所有引用列或指定的某一部分引用列设置为 null。只能为 ON DELETE 操作指定一部分列。

SET DEFAULT [ ( column_name [, ... ] ) ]

将所有引用列或指定的某一部分引用列设置为其默认值。只能为 ON DELETE 操作指定一部分列。(如果默认值不为 null,则被引用表必须包含一个与默认值匹配的行,否则操作将失败。)

匹配类型

Aurora DSQL 支持以下匹配类型:

MATCH SIMPLE(默认)

允许任意外键列为 null。如果其中任一列为 null,则不要求该行在被引用表中有匹配项。

MATCH FULL

除非所有外键列都为 null,否则禁止多列外键的某个列为 null。如果这些列都为 null,则不要求该行在被引用表中有匹配项。

您可以对引用列应用 NOT NULL 约束来防止出现此类情况。

可延迟性

您可通过指定外键约束的可延迟性来控制该约束的检查时间:

NOT DEFERRABLE(默认)

Aurora DSQL 会在每个语句执行后立即检查该约束。您无法使用 SET CONSTRAINTS 将该约束更改为延迟检查。

DEFERRABLE

可以使用 SET CONSTRAINTS 将约束延迟到事务结束时再检查。如果没有 INITIALLY 子句,则默认为 INITIALLY IMMEDIATE。

DEFERRABLE INITIALLY IMMEDIATE

默认情况下,Aurora DSQL 会在每个语句执行后检查该约束,但您可在事务中使用 SET CONSTRAINTS ... DEFERRED 延迟该约束。

DEFERRABLE INITIALLY DEFERRED

默认情况下,Aurora DSQL 会在事务提交时检查该约束。您可以在事务中使用 SET CONSTRAINTS ... IMMEDIATE 将该约束更改为即时检查。

有关在事务中更改约束检查时间的更多信息,请参阅 SET CONSTRAINTS。

仅限外键约束

在 Aurora DSQL 中,DEFERRABLE 选项仅适用于外键约束。

外键约束示例

假设您有一个存储产品信息的表:

CREATE TABLE products ( product_no integer PRIMARY KEY, name text, price numeric );

现在您需要一个表来存储这些产品的订单。您需要确保订单表包含对实际存在的产品的引用。在订单表中定义一个引用产品表的外键约束:

CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer REFERENCES products (product_no), quantity integer );

现在,您无法创建包含未出现在产品表中的非 NULL product_no 条目的订单。

在此情况下,订单表是引用表,而产品表是被引用表。同样,也存在对应的引用列和被引用列。

可以将上述命令简写为:

CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer REFERENCES products, quantity integer );

如果省略列列表,则 Aurora DSQL 将使用被引用表的主键作为被引用列。

您可以按常规方式为外键约束指定自有名称:

CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer CONSTRAINT fk_product REFERENCES products, quantity integer );

外键也可以约束和引用一组列。此时,它需要采用表约束形式:

CREATE TABLE inventory ( warehouse_id integer, product_no integer, quantity integer, PRIMARY KEY (warehouse_id, product_no) ); CREATE TABLE shipments ( shipment_id integer PRIMARY KEY, warehouse_id integer, product_no integer, FOREIGN KEY (warehouse_id, product_no) REFERENCES inventory (warehouse_id, product_no) );

受约束列的数量和类型必须与被引用列的数量和类型兼容。

一个表可具有多个外键约束。这用于实现表与表之间的多对多关系:

CREATE TABLE order_items ( product_no integer REFERENCES products, order_id integer REFERENCES orders, quantity integer, PRIMARY KEY (product_no, order_id) );

外键约束可以引用自身所属的表。这称为自引用外键。例如,如果您希望表中的行表示树结构的节点,可以这样写:

CREATE TABLE tree ( node_id integer PRIMARY KEY, parent_id integer REFERENCES tree, name text );

顶层节点具有 NULL parent_id,而非 NULL parent_id 条目受到约束,只能引用表中的有效行。

您可以指定引用操作来控制删除或更新被引用行时发生的情况。以下示例使用 ON DELETE RESTRICT 来防止删除仍被订单引用的产品:

CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer REFERENCES products ON DELETE RESTRICT, quantity integer );

使用 RESTRICT 时,如果尝试删除被订单引用的产品,则会立即产生错误。使用默认的 NO ACTION 时,如果约束被声明为 DEFERRABLE,则可以将检查延迟到事务结束时执行。

要创建可延迟到事务结束时检查的外键,请使用 DEFERRABLE 选项。如果需要在同一事务中向两个表插入行而无需考虑插入顺序时,这会非常有用:

CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer REFERENCES products DEFERRABLE INITIALLY DEFERRED, quantity integer );

如果使用 DEFERRABLE INITIALLY DEFERRED,则约束直到提交时才会被检查。您可以在产品行不存在时先插入订单行,只要产品行在事务提交时存在即可。

要将 MATCH FULL 与复合外键结合使用(这要求所有引用列都为 null 或都不为 null),可以这样写:

CREATE TABLE shipments ( shipment_id integer PRIMARY KEY, warehouse_id integer, product_no integer, FOREIGN KEY (warehouse_id, product_no) REFERENCES inventory (warehouse_id, product_no) MATCH FULL );