16.SQL语句: CREATE SEQUENCE 到 DELETE
本章包含以下内容SQL语句:
-
CREATE SEQUENCE
-
CREATE SERVER
-
CREATE STATISTICS
-
CREATE SUBSCRIPTION
-
CREATE SYNONYM
-
CREATE TABLE
-
CREATE TABLE AS
-
CREATE TABLESPACE
-
CREATE TEXT SEARCH CONFIGURATION
-
CREATE TEXT SEARCH DICTIONARY
-
CREATE TEXT SEARCH PARSER
-
CREATE TEXT SEARCH TEMPLATE
-
CREATE TRANSFORM
-
CREATE TRIGGER
-
CREATE TYPE
-
CREATE TYPE BODY
-
CREATE USER
-
CREATE USER MAPPING
-
CREATE VIEW
-
DEALLOCATE
-
DECLARE
-
DELETE
16.1.CREATE SEQUENCE
CREATESEQUENCE创建新的序列数 发生器。这涉及到名称。``name``创造和初始化 新的特殊单行表。该发生器将由发出该命令的用户拥有。如果给出一个模型名称,序列将在指定的模型中创建。否则,它将被创建 在当前模式中创建。临时序列存在于特殊模式中,因此在创建临时序列时 模式名不能给出。序列名必须与任何其他序列、表、索引相同。 视图或外表名称不同。
函数可以在序列创建后使用
nextval、currval以及setval操作序列。这些函数在序列操作函数中有介绍。虽然不能直接更新序列,但可以使用此查询:
SELECT * FROM name;检查序列的参数和当前状态。特别是,序列
last_value域显示任何会话最后一次获得的值(当然, 在被打印时该值可能已经过时了,因为可能有其他会话正在执行nextval调用)。
无
CREATE [ TEMPORARY | TEMP ] SEQUENCE [ IF NOT EXISTS ] name [ INCREMENT [ BY ] increment ] [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] [ START [ WITH ] start ] [ CACHE cache ] [ NOCACHE ] [ [ NO ] CYCLE ] [ NOCYCLE ] [ ORDER ] [ NOORDER ] [ OWNED BY { table_name.column_name | NONE } ]
TEMPORARYorTEMP如果指定,只会为会话创建序列对象,退出会话时自动 删除它。当临时序列存在时,现有的同名永久序列(在本次会话中) 它会变得不可见,但同名永久序列可以用模式限定的名称引用。
IFNOTEXISTS如果有同名关系,不要犯错误。在这种情况下,会发出一个 提示。请注意,这并不能保证现有的关系与即将到来的序列相似 -- 它甚至可能 都不是序列。
name要创建的序列名称(可以由模式限制)。
data_type可选的子句
ASdata_type制定序列数据类型。有效类型是smallint、integer、 和bigint。默认是bigint。 数据类型决定了序列的默认最小和最大值。
increment可选的子句
INCREMENTBYincrement指定为了 在当前序列值上创建新值。正值将创建上升值 负值创建一个下降序列。默认值是 1。
minvalueNOMINVALUE可选的子句
MINVALUEminvalue决定一个序列 能产生的最小值。如果提供此子句或指定NOMINVALUE,然后使用默认值。 升序列的默认值为1。降序列的默认值为数据类型的最小值。
maxvalueNOMAXVALUE可选的子句
MAXVALUEmaxvalue决定该序列 最大值。如果不提供此子句或指定NOMAXVALUE,然后将使用默认值。 升序列的默认值是数据类型的最大值。降序列的默认值为-1。
start可选的子句
STARTWITHstart允许序列从任何方面进行 地方开始。对于上升序列和下降序列来说,默认的开始值分别是``minvalue``和``maxvalue``。
cacheNOCYCLE可选的子句
CACHEcache指定预分配多少 将序列数放入内存中快速访问。最小值为 1 (一次只生成 一个值,即没有缓存),默认值也是 1。指定
NOCACHE,即没有缓存,缓存值为1。
CYCLENOCYCLENOCYCLE对于上升序列和下降序列,
CYCLE允许序列选项 在分别达到``maxvalue``和``minvalue``时回卷。如果是 这个限制,下一个数字将分别是``minvalue``和``maxvalue``。如果指定了
NOCYCLE,当序列达到其最大值时 后任何nextval如果调用会回到错误。CYCLE和NOCYCLE都没有 被指定,默认为NOCYCLE。
NOCYCLE等价于NOCYCLE。
ORDERNOORDER
ORDER与NOORDER只在语法层面兼容Oracle数据库没有实现相应的功能。
OWNEDBYtable_name.column_nameOWNEDBYNONE
OWNEDBY选项导致序列与特定的表列相关 这样,如果该列(或整个表)被删除,该序列也将被自动删除。 指定的表必须在同一模式下拥有与序列相同的所有者。默认选项OWNEDBYNONE指定序列不与列相关。
创建一个称作
serial的上升序列,从 101 开始:CREATE SEQUENCE serial START 101;从这个序列中选取下一个数字:
SELECT nextval('serial'); nextval --------- 101再从这个序列中选取下一个数字:
SELECT nextval('serial'); nextval --------- 102在一个
INSERT命令中使用这个序列:INSERT INTO distributors VALUES (nextval('serial'), 'nothing');在一次
COPY FROM后更新新列值:BEGIN; COPY distributors FROM 'input_file'; SELECT setval('serial', max(id)) FROM distributors; END;
CREATE SEQUENCE符合SQL 标准,不过下列除外:
使用
nextval()而不是标准的NEXT VALUE FOR表达式获取下一个值。
OWNED BY子句是一种KingbaseES扩展。
使用
DROP SEQUENCE移除一个序列。序列是基于
bigint算法的,因此范围是不能超过一个八字节 整数的范围(-9223372036854775808 到 9223372036854775807)。由于
nextval和setval调用绝不会回滚, 如果需要序数的“无间隙”分配,则不能使用序列对象。可以 通过在一个只包含一个计数器的表上使用排他锁来构建无间隙的分配, 但是这种方案比序列对象开销更大,特别是当有很多事务并发请求序数 时。如果对一个将由多个会话并发使用的序列对象使用了大于 1 的``cache``设置,可能会得到意想不到的结果。 每个会话会在访问该序列对象时分配并且缓存后续的序列值,并且相应地增加 该序列对象的
last_value。然后,在该会话中下一次nextval会做 ``cache``-1,并且简单地 返回预分配的值而不修改序列对象。因此,任何已分配但没有在会话中使用的 数字将会在该会话结束时丢失,导致该序列中的“空洞”。进一步,尽管多个会话能分配到不同的序列值,这些值可能会在所有会话都被 考虑时生成出来。例如, ``cache``的设置为 10,会话 A 可能储存值 1..10 并且返回
nextval=1,然后会话 B 可能储存值 11..20 并且在 A 生成nextval=2 之前返回nextval=11。因此,如果 ``cache``设置为 1,可以 安全地假设nextval值被顺序地生成。如果``cache``设置大于 1,就只能假定nextval值都是可区分的,但不能保证它们被完全地顺序生成。 还有,last_value将反映服务于任意会话的最后一个值,不管它 是否已经被nextval返回过。另一个考虑是,在这样一个序列上执行的
setval将不会通知 其他会话,直到它们用尽了任何已缓存的预分配值。
16.2. CREATE SERVER
CREATE SERVER定义一个新的外部服务器。定义该服务器的用户会成为拥有者。外部服务器通常包装了外部数据包装器用来访问一个外部数据源所需的 连接信息。额外的用户相关的连接信息可以通过用户映射的方式来指定。
服务器名称在数据库中必须唯一。
创建服务器要求所使用的外部数据包装器上的
USAGE特权。
CREATE SERVER [ IF NOT EXISTS ] server_name [ TYPE 'server_type' ] [ VERSION 'server_version' ]
FOREIGN DATA WRAPPER fdw_name
[ OPTIONS ( option 'value' [, ... ] ) ]
IF NOT EXISTS如果已经存在同名的服务器,不要抛出错误。在这种情况下发出一个通知。 请注意,不能保证现有服务器与要创建的服务器类似。
server_name要创建的外部服务器的名称。
server_type可选的服务器类型,可能对外部数据包装器有用。
server_version可选的服务器版本,可能对外部数据包装器有用。
fdw_name管理该服务器的外部数据包装器的名称。
OPTIONS ( option'value' [, ... ] )这个子句为服务器指定选项。这些选项通常定义该服务器的连接细节, 但是实际的名称和值取决于该服务器的外部数据包装器。
创建使用外部数据包装器
kingbase_fdw``的服务器\ ``myserver:CREATE SERVER myserver FOREIGN DATA WRAPPER kingbase_fdw OPTIONS (host 'foo', dbname 'foodb', port '54321');
CREATE SERVER符合 ISO/IEC 9075-9 (SQL/MED)。
16.3. CREATE STATISTICS
CREATE STATISTICS将创建一个新的扩展统计对象, 追踪指定表、外部表或物化视图的数据。该统计对象将在当前数据库中创建, 被发出该命令的用户所有。如果给定了模式名(比如,
CREATE STATISTICS myschema.mystat ...), 那么在给定的模式中创建统计对象。否则在当前模式中创建。 统计对象的名称必须与相同模式中的任何其他统计对象不同。
你必须是表的所有者才能创建读取它的统计对象。不过,一旦创建,统计对象的所有权与基础表无关。
CREATE STATISTICS [ IF NOT EXISTS ] statistics_name
[ ( statistics_kind [, ... ] ) ]
ON column_name, column_name [, ...]
FROM table_name
IF NOT EXISTS如果具有相同名称的统计对象已经存在,不会抛出一个错误,只会发出一个提示。 请注意,这里只考虑统计对象的名称,不考虑其定义细节。
statistics_name要创建的统计对象的名称(可以有模式限定)。
statistics_kind在此统计对象中计算的统计种类。目前支持的种类是启用n-distinct统计的
ndistinct,以及启用功能依赖性统计的dependencies,mcv启用最常用的值列表。 如果省略该子句,则统计对象中将包含所有支持的统计类型。
column_name被计算的统计信息包含的表格列的名称。至少必须给出两个列名。列名的顺序无关紧要。
table_name包含计算统计信息的列的表的名称(可以是模式限定的)。
用两个功能相关的列创建表
t1, 即第一列中的值的信息足以确定另一列中的值。然后, 在这些列上构建函数依赖关系统计信息:CREATE TABLE t1 ( a int, b int ); INSERT INTO t1 SELECT i/100, i/500 FROM generate_series(1,1000000) s(i); ANALYZE t1; -- 匹配行的数量将被大大低估: EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0); CREATE STATISTICS s1 (dependencies) ON a, b FROM t1; ANALYZE t1; -- 现在行计数估计会更准确: EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);如果没有函数依赖性统计信息,规划器会认为两个
WHERE条件是独立的, 并且会将它们的选择性乘以一起来返回满足条件的行,以致得到的行数被低估。 通过这样的统计,规划器认识到WHERE条件是多余的,就不会低估行数。创建具有两个完全相关的列的表
t2(包含相同的数据),并在这些列上创建一个MCV列表:CREATE TABLE t2 ( a int, b int ); INSERT INTO t2 SELECT mod(i,100), mod(i,100) FROM generate_series(1,1000000) s(i); CREATE STATISTICS s2 (mcv) ON a, b FROM t2; ANALYZE t2; -- valid combination (found in MCV) EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1); -- invalid combination (not found in MCV) EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2);MCV列表为计划者提供了关于表中通常出现的特定值的更详细的信息,以及未出现在表中的值的组合的选择的上限,从而使它能够在两种情况下生成更好的估计值。
SQL标准中没有
CREATE STATISTICS命令。
16.4. CREATE SUBSCRIPTION
CREATE SUBSCRIPTION为当前数据库添加一个新的订阅。 订阅名称必须与数据库中任何现有的订阅不同。订阅表示到发布者的复制连接。因此,此命令不仅在本地目录中添加定义, 还会在发布者上创建复制插槽。
在运行此命令的事务提交时,将启动逻辑复制工作器以复制新订阅的数据。
创建复制槽时(默认行为),
CREATE SUBSCRIPTION不能在事务块内部执行。如果复制插槽不是作为同一命令的一部分创建的,则创建连接到相同数据库集群的订阅 (例如,在同一集群中的数据库之间进行复制或在同一个数据库中进行复制)只能成功 否则,
CREATE SUBSCRIPTION调用将挂起。要做到这一点, 单独创建复制插槽(使用函数sys_create_logical_replication_slot和插件名称pgoutput),并使用参数create_slot = false创建订阅。这是一个实施限制,可能会在未来的版本中解除。
CREATE SUBSCRIPTION subscription_name
CONNECTION 'conninfo'
PUBLICATION publication_name [, ...]
[ WITH ( subscription_parameter [= value] [, ... ] ) ]
subscription_name新订阅的名称。
CONNECTION 'conninfo'连接发布者的字符串。
PUBLICATION publication_name要订阅的发布者上的发布名称。
WITH ( subscription_parameter[=value] [, ... ] )该子句指定订阅的可选参数。支持的参数有:
copy_data(boolean)指定在复制启动后是否应复制正在订阅的发布中的现有数据。 默认值是
true。
create_slot(boolean)指定该命令是否要在发布者上创建复制槽。默认值是
true。
enabled(boolean)指定订阅是否应该主动复制,或者是否应该只是设置,但尚未启动。 默认值是
true。
slot_name(string)要使用的复制插槽的名称。默认行为是使用订阅名称作为插槽的名称。
当
slot_name设置为NONE时, 将不会有复制槽与订阅关联。这在需要稍后手动设置复制槽的情况下会使用。 这样的订阅必须同时enabled并且create_slot设置为false。
synchronous_commit(enum)该参数的值会覆盖synchronous_commit设置。 默认值是
off。对于逻辑复制使用
off是安全的: 如果订阅者由于缺少同步而丢失事务,数据将从发布者重新发送。进行同步逻辑复制时,不同的设置可能是合适的。 逻辑复制工作者向发布者报告写入和刷新的位置,当使用同步复制时, 发布者将等待实际刷新。这意味着,当订阅用于同步复制时, 将订阅者的
synchronous_commit设置为off可能会增加发布服务器上COMMIT的延迟。 在这种情况下,将synchronous_commit设置为local或更高是有利的。
connect(boolean)指定
CREATE SUBSCRIPTION是否应该连接到发布者。 将其设置为false将会改变默认值enabled、create_slot和copy_data为false。不允许将
connect设置为false的同时将enabled、create_slot或copy_data设置为true。因为该选项设置为
false时不会建立连接, 因此表没有被订阅,所以当启用订阅后,不会复制任何内容。 需要运行ALTER SUBSCRIPTION ... REFRESH PUBLICATION才能订阅表。
创建一个到远程服务器的订阅,复制发布
mypublication和insert_only中的表,并在提交时立即开始复制:CREATE SUBSCRIPTION mysub CONNECTION 'host=192.168.1.50 port=54321 user=foo dbname=foodb' PUBLICATION mypublication, insert_only;创建一个到远程服务器的订阅,复制
insert_only发布中的表, 并且不开始复制直到稍后启用复制。CREATE SUBSCRIPTION mysub CONNECTION 'host=192.168.1.50 port=54321 user=foo dbname=foodb' PUBLICATION insert_only WITH (enabled = false);
CREATE SUBSCRIPTION是一个KingbaseES 扩展。
16.5. CREATE SYNONYM
CREATE SYNONYM定义一个同义词。同义词是数据库对象的一个别名,常用于简化对象访问和提高对象访问的安全性。在使用同义词时,数据库将它翻译成对应数据库对象的名字。与视图类似,同义词并不占用实际存储空间,只在数据字典中保存了同义词的定义。用户可以通过访问对象的同义词,来间接访问对象。
CREATE OR REPLACE SYNONYM与之相似,但是如果已经存在一个同名同义词,该同义词会被替换。如果给定了一个模式名(例如
CREATE SYNONYM myschema.mysynonym ...),那么该同义词会被创建在指定的模式中。否则,它会被创建在当前模式中。同义词的名称不能与同一模式中任何其他同义词同名。
要创建同义词,必须拥有CREATE SYNONYM 的系统权限。
CREATE [ OR REPLACE ] [ PUBLIC ] SYNONYM syn_name FOR obj_name
PUBLIC指定创建同义词的类型,指定PUBLIC为公有同义词,公有同义词创建在PUBLIC模式下,用户创建公有同义词时候,可以不用指定模式。创建私有同义词必须指定模式(在当前模式为PUBLIC的时候),模式不可为PUBLIC,同时不可以指定PUBLIC参数。
syn_name要创建的同义词的名字(可以是模式限定的)。
obj_name同义词引用对象(可以是模式限定的)。表、视图、物化视图、同义词、序列、存储过程、函数、类型都可以作为同义词引用对象
同义词和引用对象之间没有强依赖关系(不检查引用对象是否存在),同义词也无状态可言,一直是有效。例如引用对象不存在:
CREATE SCHEMA schm; CREATE SYNONYM schm.syn_tab FOR public.tab; --tab不存在 SELECT * FROM schm.syn_tab; ERROR: relation "SCHM.SYN_TAB" does not exist LINE 1: SELECT * FROM schm.syn_tab; SELECT * FROM SYS_SYNONYM WHERE synname = 'SYN_TAB'; --同义词定义信息 SYNNAME | SYNNAMESPACE | SYNOWNER | REFOBJNSPNAME | REFOBJNAME ---------+--------------+----------+---------------+------------ SYN_TAB | 16385 | 10 | PUBLIC | TAB SELECT status FROM ALL_OBJECTS WHERE object_name = 'SYN_TAB'; --查看同义词状态 STATUS -------- VALID引用对象存在,删除引用对象(可删除),同义词状态有效:
CREATE TABLE public.tb(id int); INSERT INTO TB VALUES(1); CREATE SYNONYM schm.syn_tb FOR public.tb; SELECT * FROM SYS_SYNONYM WHERE synname = 'SYN_TB'; SYNNAME | SYNNAMESPACE | SYNOWNER | REFOBJNSPNAME | REFOBJNAME ---------+--------------+----------+---------------+------------ SYN_TB | 16385 | 10 | PUBLIC | TB (1 row) SELECT status FROM ALL_OBJECTS WHERE object_name = 'SYN_TB'; STATUS -------- VALID SELECT * FROM schm.syn_tb; ID ---- 1 DROP TABLE public.tb; SELECT status FROM ALL_OBJECTS WHERE object_name = 'SYN_TB'; STATUS -------- VALID SELECT * FROM schm.syn_tb; ERROR: relation "SCHM.SYN_TB" does not exist LINE 1: SELECT * FROM schm.syn_tb;所创建的公有同义词在PUBLIC模式下,公有同义词可以和私有同义词同名。例如:
CREATE PUBLIC SYNONYM syn_tabl FOR tabl; CREATE SYNONYM schm.syn_tabl FOR tabl; SELECT syn.synname, sp.nspname FROM SYS_SYNONYM syn, SYS_NAMESPACE sp WHERE syn.synnamespace = sp.oid; SYNNAME | NSPNAME ------------------+------------ SYN_TABL | PUBLIC SYN_TABL | SCHM创建公有同义词不可指定模式,创建私有同义词必须指定模式(在当前模式为PUBLIC的时候)。例:
CREATE PUBLIC SYNONYM schm.syn_tt FOR public.tab; ERROR: PUBLIC can not be used when schema name specified for synonym name LINE 1: CREATE PUBLIC SYNONYM schm.syn_tt FOR public.tab; CREATE SYNONYM syn_tt FOR public.tab; ERROR: missing or invalid synonym identifier,the current default schema is public set SEARCH_PATH to schm,public; CREATE SYNONYM syn_tt FOR public.tab; CREATE SYNONYM创建私有同义词不可指定为PUBLIC。
CREATE SYNONYM public.syn_tab1 FOR public.tab1; ERROR: missing or invalid synonym identifier LINE 1: CREATE SYNONYM public.syn_tab1 FOR public.tab1;同义词的使用,和使用引用对象一样。
CREATE TABLE public.tab1(id int); INSERT INTO public.tab1 VALUES(1); CREATE PUBLIC SYNONYM syn_tab1 FOR public.tab1; SELECT * FROM syn_tab1; ID ---- 1 CREATE OR REPLACE INTERNAL FUNCTION public.increment(i integer) RETURNS integer AS $$ BEGIN RETURN i + 1; END; $$ LANGUAGE plsql; CREATE SYNONYM syn_inc FOR public.increment; CALL syn_inc(3); SYN_INC --------- 4
CREATE SYNONYM是KingbaseES的一种语言扩展。兼容Oracle同义词语法。
16.6. CREATE TABLE
CREATE TABLE将在当前数据库中创建一个新的、初始为空的表。该表将由发出该命令的用户所拥有。如果给定了一个模式名(例如
CREATE TABLE myschema.mytable ...),那么该表被创建在指定的模式中。否则它被创建在当前模式中。该表的名称必须与同一个模式中的任何其他表、序列、索引、视图或外部表的名称区分开。
CREATE TABLE也会自动地创建一个数据类型来表示对应于该表一行的组合类型。因此,表不能用同一个模式中任何已有数据类型的名称。可选的约束子句指定一个插入或更新操作要成功,新的或更新过的行必须满足的约束(测试)。一个约束是一个 SQL 对象,它帮助以多种方式定义表中的合法值集合。
有两种方式来定义约束:表约束和列约束。一个列约束会作为列定义的一部分定义。一个表约束定义不与一个特定列绑定,并且它可以包含多于一个列。每一个列约束也可以被写作一个表约束,列约束只是一种当约束只影响一列时方便书写的记号习惯。
要能创建一个表,你必须分别具有所有列类型或
OF子句中类型的USAGE特权。
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [ { column_name data_type [ INVISIBLE | VISIBLE ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option ... ] } [, ... ] ] ) [ INHERITS ( parent_table [, ... ] ) ] [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) [ partition_extented_spec ] ] [ USING method ] [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] [ { ENABLE | DISABLE } [ VALIDATE | NOVALIDATE ] constraint [ ... ] ] [ ENCRYPTED [BY tablekey ]] CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name OF type_name [ ( { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ] | table_constraint } [, ... ] ) ] [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) [ partition_extented_spec ] ] [ USING method ] [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] [ ENCRYPTED [BY tablekey ]] CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name PARTITION OF parent_table [ ( { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ] | table_constraint } [, ... ] ) ] { FOR VALUES partition_bound_spec | DEFAULT } [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] [ USING method ] [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] [ ENCRYPTED [BY tablekey ]]其中 column_constraint 是:
[ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) [ NO INHERIT ] | DEFAULT default_expr | GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | UNIQUE index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ { ENABLE | DISABLE } [ VALIDATE | NOVALIDATE ] ]table_constraint 是:
[ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | UNIQUE ( column_name [, ... ] ) index_parameters | PRIMARY KEY ( column_name [, ... ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ { ENABLE | DISABLE } [ VALIDATE | NOVALIDATE ] ]like_option 是:
{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }partition_bound_spec 是:
IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal )UNIQUE、PRIMARY KEY以及EXCLUDE约束中的index_parameters是:
[ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ]一个EXCLUDE约束中的exclude_element是:
{ column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]其中 constraint 是:
{ CONSTRAINT constraint_name | UNIQUE ( column_name [, ... ] ) | PRIMARY KEY }partition_extented_spec 是:
[ INTERVAL ( interval_expr ) [ STORE IN ( tablespace_name [, …]) ]] [ SUBPARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) [ { hash_subparts_by_quantity | subpartition_template } ] ] [ ( PARTITION partition [partition_bound_spec_ex] [ TABLESPACE tablespace_name ] [ ( SUBPARTITION subpartition [subpartition_bound_spec] [ TABLESPACE tablespace_name ] [, ... ] ) | SUBPARTITIONS numeric_literal [ STORE IN ( tablespace_name [, ... ] ) ] ] [, ... ] ) | PARTITIONS numeric_literal [ STORE IN ( tablespace_name [, ... ] ) ] ]hash_subparts_by_quantity 是:
SUBPARTITIONS numeric_literal [ STORE IN ( tablespace_name [, …] ) ]subpartition_template 是:
SUBPARTITION TEMPLATE ( SUBPARTITION [subpartition] [subpartition_bound_spec] [ TABLESPACE tablespace_name ] [, …] )partition_bound_spec_ex 是:
VALUES LESS THEN ( { partition_bound_expr | MAXVALUE } [, …] ) | VALUES ( partition_bound_expr [, …] | DEFAULT )subpartition_bound_spec 是:
VALUES LESS THEN ( { partition_bound_expr | MAXVALUE } [, …] ) | VALUES ( partition_bound_expr [, …] | DEFAULT )
TEMPORARYorTEMP如果指定,该表被创建为一个临时表。
自动清理守护进程不能访问并且因此也不能清理或分析临时表。由于这个原因,应该通过会话的SQL命令执行合适的清理和分析操作。例如,如果一个临时表将要被用于复杂的查询,最好在把它填充完毕后在其上运行
ANALYZE。可以选择将
GLOBAL或LOCAL写在TEMPORARY或TEMP的前面。创建临时表时若不指定GLOBAL或LOCAL,则默认值指定为LOCAL。
GLOBAL全局临时表的表定义是持久的,而表数据是临时的。
LOCAL本地临时表的表定义和表数据都是临时的,会在会话退出后被删除。
本地临时表和全局临时表在各个会话之间数据彼此不影响;表中的数据都可以在事务结束之后删除,或者连接退出之后删除;数据都存在在临时表空间中;临时表都不记录日志。
本地临时表和全局临时表有如下四点区别:
1.本地临时表在临时模式下,用户不可以指定;但是全局临时表创建在用户指定模式下;
2.本地临时表对象本身并不是一直存在,在会话退出后,本地临时表会被删除;全局临时表创建之后,一直存在,除非显示去删除它。
3.删除本地临时表,不受其他会话影响;但是删除全局临时表时,所有会话都不能持有全部临时表的数据。
4.全局临时表不支持外键约束也不支持其他表引用全局临时表作为外键约束,而本地临时表没有这个要求。
UNLOGGED如果指定,该表被创建为一个不受日志记录的表。被写入到不做日志的表中的数据不会被写到预写式日志中,这让它们比普通表快非常多。不过,它们在崩溃时是不安全的:一个不做日志的表在一次崩溃或非干净关闭之后会被自动地截断。一个不做日志的表中的内容也不会被复制到后备服务器中。在一个不做日志的表上创建的任何索引也会自动地不被日志记录。
IF NOT EXISTS如果一个同名关系已经存在,不要抛出一个错误。在这种情况下会发出一个提示。注意这不保证现有的关系是和将要被创建的表相似的东西。
table_name要被创建的表名(可以选择用模式限定)。
OF type_name创建一个类型化的表,它的结构取自于指定的组合类型(名字可以选择用模式限定)。一个类型化的表和它的类型绑定在一起,例如如果类型被删除,该表也将被删除(用
DROP TYPE ... CASCADE)。当一个类型化的表被创建时,列的数据类型由底层的组合类型决定而没有在
CREATE TABLE命令中直接指定。但是CREATE TABLE命令可以对表增加默认值和约束,并且可以指定存储参数。
column_name要在新表中创建的一列的名称。
data_type该列的数据类型。这可以包括数组说明符。更多关于KingbaseES支持的数据类型,请参考 数据类型 。
INVISIBLE | VISIBLE该列的隐含属性,关于隐含列的特征参考Oracle语言兼容特性中关于隐含列的描述, INVISIBLE 表示该列在创建时指定为隐含列,相反地,如果不指定或者指定为VISIBLE 则表示该列是非隐含列。
COLLATE collation
COLLATE子句为该列(必须是一种可排序数据类型)赋予一个排序规则。如果没有指定,将使用该列数据类型的默认排序规则。
INHERITS ( parent_table[, ... ] )可选的
INHERITS子句指定一个表的列表,新表将从其中自动地继承所有列。父表可以是普通表或者外部表。
INHERITS的使用在新的子表和它的父表之间创建一种持久的关系。对于父表的模式修改通常也会传播到子表,并且默认情况下子表的数据会被包括在对父表的扫描中。如果在多个父表中存在同名的列,除非父表中每一个这种列的数据类型都能匹配,否则会报告一个错误。如果没有冲突,那么重复列会被融合来形成新表中的一个单一列。如果新表中的列名列表包含一个也是继承而来的列名,该数据类型必须也匹配继承的列,并且列定义会被融合成一个。如果新表显式地为列指定了任何默认值,这个默认值将覆盖来自该列继承声明中的默认值。否则,任何父表都必须为该列指定相同的默认值,或者会报告一个错误。
CHECK约束本质上也采用和列相同的方式被融合:如果多个父表或者新表定义中包含相同的命名CHECK约束,这些约束必须全部具有相同的检查表达式,否则将报告一个错误。具有相同名称和表达式的约束将被融合成一份拷贝。一个父表中的被标记为NO INHERIT的约束将不会被考虑。注意新表中一个未命名的CHECK约束将永远不会被融合,因为那样总是会为它选择一个唯一的名字。列的
STORAGE设置也会从父表复制过来。如果父表中的列是标识列,那么该属性不会被继承。如果需要, 可以将子表中的列声明为标识列。
PARTITION BY { RANGE | LIST | HASH } ( { column_name| (expression) } [opclass] [, ...] )可选的
PARTITION BY子句指定了对表进行分区的策略。 这样创建的表称为分区表。 带括号的列或表达式列表形成表的分区键。 使用范围或哈希分区时,分区键可以包含多个列或表达式(最多32个,但在构建 KingbaseES时可以更改此限制),但对于列表分区, 分区键必须由单个列或表达式组成。范围和列表分区需要一个btree操作符类,而哈希分区需要一个哈希操作符类。如果没有显式指定运算符类,则使用适当类型的默认运算符类;如果不存在缺省操作符类,则会引发错误。当使用哈希分区时,使用的操作符类必须实现支持函数2
分区表被分成多个子表(称为分区),它们是使用单独的
CREATE TABLE命令创建的。 分区表本身是空的。插入到表中的数据行将根据分区键中的列或表达式的值路由到分区。 如果没有现有的分区与新行中的值匹配,则会报告错误。分区表不支持
EXCLUDE约束,但是您可以在各个分区上定义这些约束。可选的
partition_extented_spec子句支持兼容Oracle的分区定义语法,可以在一条语句中定义单层分区表和复合分区表。分区自动继承分区表的全部列定义、主外键索引和约束、唯一索引和约束、NOT NULL约束和CHECK约束。分区自动继承分区表的全局或者本地临时表属性。
有关表分区的更多讨论,参考 分区 。
PARTITION OF parent_table{ FOR VALUESpartition_bound_spec| DEFAULT }创建指定父表的分区。可以使用
FOR VALUES创建特定值的分区,也可以使用DEFAULT创建默认分区。``partition_bound_spec``必须对应于父表的分区方法和分区键,并且不能与父表的任何现有分区重叠。
IN中的表单用于列表分区,FROM和TO中的表单用于范围分区,WITH中的表单用于哈希分区。``partition_bound_expr``是任意无变量表达式(使子查询、窗口函数、聚合函数和集返回函数是不允许的)。它的数据类型必须与相应分区键列的数据类型匹配。表达式在表创建时只计算一次,因此它甚至可以包含volatile表达式,比如
CURRENT_TIMESTAMP。在创建列表分区时,
NULL能够被指定来表示,允许分区键列为空。但是,对于给定的父表,不能有多个这样的列表分区。NULL不能指定范围分区。在创建一个范围分区时,指定的下界
FROM是一个包含范围,而指定的上界TO是一个排他界限。也就是说,从FROM列表中指定的值是该分区对应分区键列的有效值,而从TO列表中的值则不是。 注意,这个语句必须根据行比较的规则来理解。 例如,给定PARTITION BY RANGE (x,y),FROM (1, 2) TO (3, 4)的分区允许x=1绑定任意y>=2,x=2绑定任意非空y,x=3绑定任意y<4.特殊值
MINVALUE和MAXVALUE可以在创建范围分区时使用,以指示列的值没有下限或上限。 例如,使用FROM (MINVALUE) TO (10)定义的分区允许任何小于10的值, 使用FROM (10) TO (MAXVALUE)定义的分区允许任何大于或等于10的值。当创建一个包含多个列的范围分区时,使用
MAXVALUE作为下界的一部分,使用MAXVALUE作为上界的一部分,是有意义的。例如,使用FROM (0, MAXVALUE) TO (10, MAXVALUE)定义的分区允许第一个分区键列大于0且小于等于10的任何行。 类似地,使用FROM ('a', MINVALUE) TO ('b', MINVALUE)定义的分区允许第一个分区键列以“a”开头的任何行。注意,如果
MINVALUE或MAXVALUE被用于分区边界的一列,则必须为所有后续列使用相同的值。例如,(10, MINVALUE, 0)不是有效的边界;应该写(10, MINVALUE, MINVALUE)。还要注意一些元素类型,如
timestamp,有“infinity”的概念,它只是另一个可以存储的值。这不同于MINVALUE和MAXVALUE, 它们不是可以存储的实际值,而是表示值是无界的。MAXVALUE可以被认为是比任何其他价值都大,"infinity" 和MINVALUE小于任何其他值,包括"minus infinity"。FROM ('infinity') TO (MAXVALUE)不是一个空的范围;它只允许存储一个值— "infinity"。如果指定了
DEFAULT,那么该表将被创建为父表的默认分区。此选项不适用于哈希分区表。不适合给定父分区的任何其他分区的分区键值将被路由到默认分区。当一个表有一个现有的默认的分区,并且添加了一个新的分区时,必须扫描这个默认的分区,以确认它没有包含任何属于这个新分区的行。如果默认分区包含大量的行,那么速度可能会很慢。如果默认分区是一个外表,或者它有一个约束,证明它不能包含应该放在新分区中的行,那么扫描将被跳过。
在创建哈希分区时,必须指定模数和余数。模数必须是正整数,余数必须是小于模数的非负整数。通常,在最初设置哈希分区表时,应该选择与分区数量相等的模量,并为每个表分配相同的模量和不同的余数(参见下面的示例)。但是,并不是要求每个分区都具有相同的模量,只是散列分区表的分区之间出现的每个模量都是下一个较大的模量的因数。这使得分区的数量可以增量地增加,而不需要一次移动所有数据。例如,假设有一个具有8个分区的散列分区表,每个分区的模量为8,但是需要将分区数量增加到16。您可以分离其中一个模数-8分区,创建两个新的模数-16分区,覆盖键空间的相同部分(一个余数等于已分离分区的余数,另一个余数等于该值加上8),然后用数据重新填充它们。然后您可以对每个模数-8分区重复此操作(可能在以后的某个时间),直到没有剩余的分区。虽然在每个步骤中仍然可能涉及大量的数据移动,但是这仍然比创建一个全新的表并一次移动所有数据要好。
分区必须具有与其所属的分区表相同的列名和类型。对分区表的列名或类型的修改将自动传播到所有分区。每个分区都会自动继承
CHECK约束 , 但是单个分区可以指定附加的CHECK约束; 具有与父约束相同的名称和条件的附加约束将与父约束合并。默认值可以为每个分区单独指定。插入分区表中的行将被自动按路线发送到正确的分区。如果没有合适的分区存在,就会发生错误。
通常会影响表及其所有继承子表的TRUNCATE等操作将级联到所有分区,但也可以在单个分区上执行。请注意,删除具有
DROP TABLE的分区需要在父表上获取访问独占锁。
INTERVAL ( interval_expr ) [ STORE IN ( tablespace_name [, …]) ]可选的
INTERVAL子句指定创建Interval分区表,Interval分区表是一种特殊的范围分区表。当执行INSERT或者UPDATE时,由数据库根据定义的间隔参数自动创建新的分区。当插入或者更新记录的分区键值大于等于最高分区上限时,以最高分区上限为下边界,以最高分区上限+间隔值倍数为下边界创建一个新的分区。Interval分区表仅支持指定唯一的分区键列,类型必须是数值型或日期型。其中
interval_expr是任何无变量表达式(不允许子查询、窗口函数、聚合函数和集返回函数),它的数据类型必须与唯一分区键列的数据类型相匹配。这里的类型相匹配指的是:可以在分区边界值基础上,加上间隔值(使用+运算符)可以得到一个新的分区边界值,且数据类型不变,例如:date + interval = date。 必须使用PARTITION子句指定至少一个范围分区。不能在VALUES子句中指定MAXVALUE,也不能为分区键列指定NULL值。使用
STORE IN可以为Interval分区表指定表空间,新的分区以轮循方式使用指定的各个表空间,如果省略STORE IN时,则使用分区表的表空间。如果指定分区表为复合分区表,可选的
INTERVAL子句指定创建Interval复合分区表。如果定义了子分区模板,则新的分区将按子分区模板创建下级子分区,否则将根据子分区类型自动创建默认的子分区。
SUBPARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] )可选的
SUBPARTITION BY子句指定了对表进行二级分区的策略。这样创建的表称为复合分区表。带括号的列或表达式列表形成表的子分区键。 使用范围或哈希子分区时,子分区键可以包含多个列或表达式(最多32个,但在构建KingbaseES时可以更改此限制),但对于列表子分区,子分区键必须由单个列或表达式组成。
partition_bound_spec_ex和subpartition_bound_spec必须分别与分区和子分区的分区方法和分区键对应,而不能与其他分区和子分区重叠。VALUES用于列表分区和子分区,VALUE LESS THAN用于范围分区和子分区。
VALUE LESS THAN定义了范围分区的上边界(不包含边界值),使用分区键值与子句指定的有序值列表进行比较,满足条件的行将被存储在分区中。使用MAXVALUE可以定义分区键值的最大值,该最大值总是大于其他任何值(包括null)。如果在
VALUES后指定了NULL,表示分区允许分区键列为空。如果在VALUES后指定了DEFAULT,表示分区为默认分区。在列表分区表中仅允许存在一个NULL或DEFAULT分区,在每个复合分区表的主分区中也仅允许存在一个这样的子分区。
PARTITIONS和SUBPARTITIONS可以通过指定哈希数量方式定义多个哈希分区和子分区,numeric_literal为正整数。数据库为每个哈希分区自动分配table_name_pn的分区名称,为每个哈希子分区自动分配table_name_subpn的分区名称。使用
PARTITION可以按名称指定各个分区,并为每个分区单独指定表空间。使用TABLESPACE可以为分区单独指定表空间,如果省略会则使用分区表的表空间。 使用STORE IN可以为哈希分区或者子分区指定一个或多个表空间。表空间的数量不必等于分区的数量,表空间按顺序指定给各个哈希分区。如果分区数大于表空间数,余下的分区使用分区表的表空间。可选的
SUBPARTITION TEMPLATE子句可以为复合分区表指定子分区模板。子分区模板是默认的复合分区表分区划分方法,如果在主分区定义中指定了子分区定义,则子分区定义优先于子分区模板。
LIKE source_table[like_option... ]
LIKE指定新表将从哪一个表自动地复制所有的列名、数据类型以及它们的非空约束。和
INHERITS不同,新表和原始表在创建完成之后是完全分离的。对原始表的更改将不会被应用到新表,并且不可能在原始表的扫描中包括新表的数据。与继承不同的是,类似的复制列和约束不会与类似命名的列和约束合并。如果显式地指定了相同的名称,或者在另一个
LIKE子句中,错误就会被通知。可选的``like_option`` 子句指定所要复制的原始表的附加属性。指定
INCLUDING复制属性,指定EXCLUDING省略属性。EXCLUDING是默认的。 如果为同一类型的对象制定了多个规范,则使用最后一个规范。可用的选项有:
INCLUDING COMMENTS复制列、约束和索引的注释将被复制。默认行为是排除注释,导致新表中复制的列和约束没有注释。
INCLUDING CONSTRAINTS
CHECK约束将被复制。 列约束和表约束之间没有区别。非空约束总是复制到新表中。
INCLUDING DEFAULTS复制列定义的默认表达式将被复制。否则,将不复制默认表达式,从而导致新表中复制的列具有空默认值。注意,复制调用数据库修改函数(如
nextval)的默认值可能会在原始表和新表之间创建功能链接。
INCLUDING GENERATED复制列定义的任何生成表达式都将被复制。默认情况下,新列将是常规的基本列。
INCLUDING IDENTITY复制列定义的任何标识规范都将被复制。为新表的每个标识列创建一个新序列,与与旧表关联的序列分离。
INCLUDING INDEXES原始表上的Indexes、
PRIMARY KEY、UNIQUE、和EXCLUDE约束将在新表上创建。 新索引和约束的名称是根据默认规则选择的,而不管原始索引和约束是如何命名的。(这种行为可以避免新索引可能出现的重复命名错误。)
INCLUDING STATISTICS扩展的统计信息被复制到新表中。
INCLUDING STORAGE
STORAGE将复制复制列定义的设置。 默认行为是排除STORAGE设置, 使得新表中复制的列具有类型特定的默认设置。
INCLUDING ALL
INCLUDING ALL是选择所有可用的单独选项的缩写形式。(在INCLUDING ALL之后选择除某些特定选项外的所有选项,编写单独的EXCLUDING子句是有用的。)
LIKE子句也能被用来从视图、外部表或组合类型拷贝列定义。不适合的选项(例如来自视图的INCLUDING INDEXES)会被忽略。
CONSTRAINT constraint_name一个列约束或表约束的可选名称。如果该约束被违背,约束名将会出现在错误消息中,这样类似
列必须为正的约束名可以用来与客户端应用沟通有用的约束信息(指定包含空格的约束名时需要用到双引号)。如果没有指定约束名,系统将生成一个。
NOT NULL该列不允许包含空值。
NULL该列允许包含空值。这是默认情况。
这个子句只是提供与非标准 SQL 数据库的兼容。在新的应用中不推荐使用。
CHECK ( expression) [ NO INHERIT ]
CHECK指定一个产生布尔结果的表达式,一个插入或更新操作要想成功,其中新的或被更新的行必须满足该表达式。计算出 TRUE 或 UNKNOWN 的表达式就会成功。只要任何一个插入或更新操作的行产生了 FALSE 结果,将报告一个错误异常并且插入或更新不会修改数据库。一个被作为列约束指定的检查约束只应该引用该列的值,而一个出现在表约束中的表达式可以引用多列。当前,
CHECK表达式不能包含子查询,也不能引用当前行的列之外的变量。 可以引用系统列tableoid,但不能引用其他系统列。一个被标记为
NO INHERIT的约束将不会传播到子表。当一个表有多个
CHECK约束时,检查完NOT NULL约束后,对于每一行会以它们名称的字母表顺序来进行检查( V8.3 版本之前的KingbaseES对于CHECK约束不遵从任何特定的引发顺序)。
DEFAULT default_expr
DEFAULT子句为出现在其定义中的列赋予一个默认数据。 该值是可以使用变量的表达式(尤其是,不允许对其他列的交叉引用)。子查询也不被允许。 默认值表达式的数据类型必须匹配列的数据类型。默认值表达式将被用在任何没有为该列指定值的插入操作中。如果一列没有默认值,那么默认值为空值。
GENERATED ALWAYS AS ( generation_expr) STORED此子句将列创建为函数索引。无法写入该列,读取时将返回指定表达式的结果。
关键字
STORED表示该列将在写时计算并存储在磁盘上。生成表达式可以引用表中的其他列,但不能引用其他函数索引。所使用的任何函数和操作符都必须是不可变的。不允许引用其他表。
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options) ]该子句将列创建为标识列。 它将拥有一个隐式序列附加到它,并且新行中的列将自动从分配给它的序列中获取值。
子句
ALWAYS和BY DEFAULT确定在INSERT语句中,序列值如何优先于用户指定的值。 如果指定了ALWAYS,则只有在INSERT语句指定OVERRIDING SYSTEM VALUE时才接受用户指定的值。 如果指定了BY DEFAULT,则用户指定的值优先。 有关详细信息,请参见 INSERT 。 (在COPY命令中,无论此设置如何,都始终使用用户指定的值。)可选的``sequence_options``子句可用于覆盖序列的选项。有关详细信息,请参见 CREATE SEQUENCE 。
UNIQUE(列约束)UNIQUE ( column_name[, ... ] ) [ INCLUDE (column_name[, ...]) ] (表约束)
UNIQUE约束指定一个表中的一列或多列组成的组包含唯一的值。唯一表约束的行为与列约束的行为相同,只是表约束能够跨越多列。对于一个唯一约束的目的来说,空值不被认为是相等的。
每一个唯一表约束必须命名一个列的集合,并且它与该表上任何其他唯一或主键约束所命名的列集合都不相同(否则它将是一个被列举了两次的约束)。
在为多级分区层次结构建立唯一约束时,必须在约束定义中包含目标分区表的分区键的所有列,以及它的所有子代分区表的列。
添加唯一约束将自动在约束中使用的列或列组上创建唯一的btree索引。可选子句
INCLUDE添加到索引的一个或多个列上,在这些列上不强制唯一性。注意,虽然约束没有强制包含在列上,但它仍然依赖于它们。因此,这些列上的某些操作(例如DROP COLUMN)可能导致级联约束和索引删除。
PRIMARY KEY(列约束)PRIMARY KEY ( column_name[, ... ] ) [ INCLUDE (column_name[, ...]) ] (表约束)
PRIMARY KEY约束指定表的一个或者多个列只能包含唯一(不重复)、非空的值。一个表上只能指定一个主键,可以作为列约束或表约束。主键约束所涉及的列集合应该不同于同一个表上定义的任何唯一约束的列集合(否则,该唯一约束是多余的并且会被丢弃)。
PRIMARY KEY强制的数据约束可以看成是UNIQUE和NOT NULL的组合,不过把一组列标识为主键也为模式设计提供了元数据,因为主键标识其他表可以依赖这一个列集合作为行的唯一标识符。
PRIMARY KEY约束与放在分区表上的UNIQUE约束相同。添加
PRIMARY KEY约束将自动在约束中使用的列或列组上创建唯一的btree索引。可选的INCLUDE子句允许指定列的列表,这些列将包含在索引的非键部分中。虽然对包含的列不强制惟一性,但约束