定义新表

语法

CREATE [ GLOBAL TEMPORARY ] TABLE table_name (
  { column_name data_type [ DEFAULT default_expr ]
  [ column_constraint [ ... ] ] | table_constraint } [, ...]
  )
  [ ON COMMIT { PRESERVE ROWS | DELETE ROWS } ]
  [ TABLESPACE tablespace ]

其中 column_constraint 是:

  [ CONSTRAINT constraint_name ]
  { NOT NULL |
    NULL |
    UNIQUE [ USING INDEX TABLESPACE tablespace ] |
    PRIMARY KEY [ USING INDEX TABLESPACE tablespace ] |
    CHECK (expression) |
    REFERENCES reftable [ ( refcolumn ) ]
      [ ON DELETE action ] }
  [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED |
    INITIALLY IMMEDIATE ]

table_constraint 是:

  [ CONSTRAINT constraint_name ]
  { UNIQUE ( column_name [, ...] )
      [ USING INDEX TABLESPACE tablespace ] |
    PRIMARY KEY ( column_name [, ...] )
      [ USING INDEX TABLESPACE tablespace ] |
    CHECK ( expression ) |
    FOREIGN KEY ( column_name [, ...] )
        REFERENCES reftable [ ( refcolumn [, ...] ) ]
      [ ON DELETE action ] }
  [ DEFERRABLE | NOT DEFERRABLE ]
  [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

说明

CREATE TABLE 将在当前数据库中创建一个最初为空的新表。表将由发布命令的用户拥有。

如果给定 schema 名称(如 CREATE TABLE myschema.mytable ...),则在指定的 schema 中创建表。否则在当前 schema 中创建。临时表存在于特殊 schema 中,因此在创建临时表时可以不给定 schema 名称。表名称必须与同一 schema 中其他任何表、序列、索引或视图的名称有所区别。

CREATE TABLE 还会自动创建数据类型,以表示与表的一行对应的复合类型。因此,表不能与同一 schema 中的任何现有数据类型同名。

表不能超过 1600 列。(实际上,由于元组长度约束,有效限制会更低)。

可选约束子句指定为使插入或更新操作成功,新行或更新的行必须满足的约束(或测试)。约束是一个 SQL 对象,可通过多种方式帮助定义表中的有效值集。

定义约束的方式有两种:表约束和列约束。列约束定义为列定义的一部分。表约束定义不依赖于特定列,可以包含多个列。每个列约束也可以写为表约束。如果约束只影响一列,则列约束只是符号上便利。

参数

参数 说明
GLOBAL TEMPORARY 创建临时表。临时表和普通表的区别在于数据的管理上,临时表存储事务或会话的中间结果集,并且临时表中保存的数据只对当前会话可见,所有会话都看不到其他会话的数据,即使其他会话完成提交,也看不到数据。临时表不存在并发行为,对于当前会话都是独立的。临时表分事务级临时表和会话级临时表,请参见ON COMMIT参数。
table_name 要创建的表的名称(可能是 schema 限定的)。
column_name 要在新表中创建的列的名称。
data_type 列的数据类型。这可能包括数组说明符。
DEFAULT default_expr DEFAULT 子句为其中显示列定义的列分配默认数据值。值为任意无变量表达式(不允许对当前表中的其他列建立子查询和交叉引用)。默认表达式的数据类型必须与列的数据类型相匹配。
说明 默认表达式将用在未指定列值的任何插入操作中。如果列没有默认值,则默认值为 Null。
CONSTRAINT constraint_name 列约束或表约束的可选名称。如果未指定,则系统生成一个名称。
NOT NULL 不允许列包含 Null 值。
NULL 允许列包含 Null 值。这是默认值。

此子句仅可用于兼容非标准 SQL 数据库。我们不鼓励将它用在新应用程序中。

UNIQUE - 列约束

UNIQUE (column_name [, ...] ) - 表约束

UNIQUE 约束指定由表的一列或多个不同列构成的组只能包含唯一值。唯一表约束的行为与列约束相同,只是增加了跨多列的功能。

出于唯一约束的目的,Null 值不被视为是相等的。

每个唯一表约束必须命名一组列,这些列与为该表定义的其他任何唯一约束或主键约束所命名的一组列不同。(否则它只是列出两次的同一约束。)

PRIMARY KEY - 列约束

PRIMARY KEY ( column_name [, ...] ) - 表约束

主键约束指定表的一列或多列只能包含唯一(非重复)的非 Null 值。从技术方面而言,PRIMARY KEY 只是 UNIQUE 和 NOT NULL 的组合,不过将一组列标识为主键时还会提供有关 schema 设计的元数据,因为主键意味着其他表可以依赖于这一组列作为行的唯一标识符。

无论作为列约束还是表约束,只能为表指定一个主键。

主键约束应当命名一组列,这些列与为同一表定义的任何唯一约束所命名的其他若干组列不同。

CHECK (expression) CHECK 子句指定一个表达式,该表达式生成为使插入或更新操作成功,新行或更新的行必须满足的 Boolean 结果。表达式评估为 TRUE 或“未知”时表示成功。如果插入或更新操作的任何行生成 FALSE 结果,则会引发错误异常,并且插入或更新不会变更数据库。指定为列约束的 CHECK 约束应当仅引用该列的值,而显示在表约束中的表达式可以引用多列。

目前,CHECK 表达式不能包含子查询,也不能引用除当前行的列以外的变量。

REFERENCES reftable [ ( refcolumn ) ] [ ON DELETE action ] - 列约束

FOREIGN KEY ( column [, ...] ) REFERENCES reftable [ ( refcolumn [, ...] ) ] [ ON DELETE action ] - 表约束

这些子句指定外键约束,要求由新表的一列或多列构成的组只能包含与被引用表某行的被引用列中的值相匹配的值。如果省略 refcolumn,则使用 reftable 的主键。被引用列必须是被引用表中唯一约束或主键约束的列。
此外,当被引用列中的数据发生更改时,会对该表的列中的数据执行某些操作。ON DELETE 子句指定当被引用表中的被引用行被删除时执行的操作。即使约束是可延迟的,也不能延迟引用操作。以下是每个子句可能的操作:
  • CASCADE:分别删除引用已删除行的任何行,或将引用列的值更新为被引用列的新值。
  • SET NULL:将引用列设置为 NULL。

如果被引用列更改频繁,那么明智的做法是添加外键列的索引,以便更有效地执行与外键列关联的引用操作。

DEFERRABLE

NOT DEFERRABLE

这控制是否可以延迟约束。在每个命令之后立即检查不可延迟的约束。检查可延迟的约束可能会推迟到事务结束(使用 SET CONSTRAINTS 命令)。NOT DEFERRABLE 是默认值。目前只有外键约束才接受此子句。所有其他约束类型都不可延迟。
INITIALLY IMMEDIATE

INITIALLY DEFERRED

如果约束是可延迟的,则此子句指定检查约束的默认时间。如果约束是 INITIALLY IMMEDIATE,则在每条语句后检查它。这是默认值。如果约束是 INITIALLY DEFERRED,则仅在事务结束时检查。约束检查时间可以通过 SET CONSTRAINTS 命令更改。
ON COMMIT 可以使用 ON COMMIT 控制事务块结束时临时表的行为。两个选项是:
  • PRESERVE ROWS:会话级临时表,当断开连接或手动执行DELETE或TRUNCATE之前,临时表中的数据一直存在,并且只有当前会话可以看到,其他会话看不到。(请注意,此方面与 Oracle 数据库不兼容。Oracle 默认值为 DELETE ROWS。)
  • DELETE ROWS:事务级临时表,当COMMIT或ROLLBACK之前,这些数据一直存在,当事务提交之后,表中数据自动清除。本质上,每次提交时都会自动执行 TRUNCATE。
说明 PolarDB-O自动为每个唯一约束和主键约束创建索引,以强制实施唯一性。因此,没有必要为主键列创建显式索引。(有关更多信息,请参阅 CREATE INDEX。)

示例

创建表 dept 和表 emp:

CREATE TABLE dept (
    deptno          NUMBER(2) NOT NULL CONSTRAINT dept_pk PRIMARY KEY,
    dname           VARCHAR2(14),
    loc             VARCHAR2(13)
);
CREATE TABLE emp (
    empno           NUMBER(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,
    ename           VARCHAR2(10),
    job             VARCHAR2(9),
    mgr             NUMBER(4),
    hiredate        DATE,
    sal             NUMBER(7,2),
    comm            NUMBER(7,2),
    deptno          NUMBER(2) CONSTRAINT emp_ref_dept_fk
                        REFERENCES dept(deptno)
);

为表 dept 定义唯一表约束。可以在表的一列或多列上定义唯一表约束。

CREATE TABLE dept (
    deptno          NUMBER(2) NOT NULL CONSTRAINT dept_pk PRIMARY KEY,
    dname           VARCHAR2(14) CONSTRAINT dept_dname_uq UNIQUE,
    loc             VARCHAR2(13)
);

定义 CHECK 列约束:

CREATE TABLE emp (
    empno           NUMBER(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,
    ename           VARCHAR2(10),
    job             VARCHAR2(9),
    mgr             NUMBER(4),
    hiredate        DATE,
    sal             NUMBER(7,2) CONSTRAINT emp_sal_ck CHECK (sal > 0),
    comm            NUMBER(7,2),
    deptno          NUMBER(2) CONSTRAINT emp_ref_dept_fk
                        REFERENCES dept(deptno)
);

定义 CHECK 表约束:

CREATE TABLE emp (
    empno           NUMBER(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,
    ename           VARCHAR2(10),
    job             VARCHAR2(9),
    mgr             NUMBER(4),
    hiredate        DATE,
    sal             NUMBER(7,2),
    comm            NUMBER(7,2),
    deptno          NUMBER(2) CONSTRAINT emp_ref_dept_fk
                        REFERENCES dept(deptno),
    CONSTRAINT new_emp_ck CHECK (ename IS NOT NULL AND empno > 7000)
);

为表 jobhist 定义主键表约束。可以在表的一列或多列上定义主键表约束。

CREATE TABLE jobhist (
    empno           NUMBER(4) NOT NULL,
    startdate       DATE NOT NULL,
    enddate         DATE,
    job             VARCHAR2(9),
    sal             NUMBER(7,2),
    comm            NUMBER(7,2),
    deptno          NUMBER(2),
    chgdesc         VARCHAR2(80),
    CONSTRAINT jobhist_pk PRIMARY KEY (empno, startdate)
);

这将为列 job 分配一个文字常数默认值,并将 hiredate 的默认值作为插入行的日期。

CREATE TABLE emp (
    empno           NUMBER(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,
    ename           VARCHAR2(10),
    job             VARCHAR2(9) DEFAULT 'SALESMAN',
    mgr             NUMBER(4),
    hiredate        DATE DEFAULT SYSDATE,
    sal             NUMBER(7,2),
    comm            NUMBER(7,2),
    deptno          NUMBER(2) CONSTRAINT emp_ref_dept_fk
                        REFERENCES dept(deptno)
);

在表空间 diskvol1 中创建表 dept:

CREATE TABLE dept (
    deptno          NUMBER(2) NOT NULL CONSTRAINT dept_pk PRIMARY KEY,
    dname           VARCHAR2(14),
    loc             VARCHAR2(13)
) TABLESPACE diskvol1;