CREATE TABLE
功能描述
在当前数据库中创建一个新的空白表。
该表由命令执行者所有,但系统管理员在普通用户同名schema下创建的表,表的所有者为schema的同名用户(非系统管理员)。
注意事项
- 列存表支持的数据类型请参考列存表支持的数据类型。
- 创建列存和HDFS分区表的数量建议不超过1000个。
- 表中的主键约束和唯一约束必须包含分布列。
- 不支持修改已有表的分布列数据类型。
- 行存REPLICATION分布表不支持将系统列设置为主键。
- 如果在建表过程中数据库系统发生故障,系统恢复后可能无法自动清除之前已创建的、大小为0的磁盘文件。此种情况出现概率小,不影响数据库系统的正常运行。
- 列存表支持PARTIAL CLUSTER KEY、主键和唯一表级约束,不支持外键表级约束。
- 列存表的字段约束只支持NULL、NOT NULL和DEFAULT常量值。
- 列存表支持delta表,受表级参数enable_delta控制是否开启,受参数deltarow_threshold控制进入delta表的阈值。
- 冷热表仅支持列存分区表,依赖于可用的OBS服务。
- 冷热表仅支持默认表空间为default_obs_tbs,如需新增obs表空间可联系技术支持。
- 不建议创建普通表时指定自定义TABLESPACE。
- 创建行存表时应避免指定COMPRESS压缩属性。
- 创建HASH分布的表对象时,要确保数据分布均匀(10G以上数据量的表,倾斜率控制在10%以内)。
- 创建REPLICATION分布的表对象,要确保表数据量控制在100万行以内。
- 创建HSTORE表时,必须确保数据库GUC参数设置满足以下条件:
- autovacuum设置为on。
- autovacuum_max_workers_hstore取值大于0。
- autovacuum_max_workers取值大于autovacuum_max_workers_hstore的取值。
- 针对存在时间字段的大表(数据量5000万行以上),必须设计成分区表,根据查询特征合理设计分区间隔。
- 针对有大批量数据增删改的表,索引个数建议控制在3个以内,最多不超过5个。
- 更多开发设计规范参见总体开发设计规范。
语法格式
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name { ({ column_name data_type [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option [...] ] } [, ... ])| LIKE source_table [ like_option [...] ] } [ WITH ( {storage_parameter = value} [, ... ] ) ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS } ] [ COMPRESS | NOCOMPRESS ] [ DISTRIBUTE BY { REPLICATION | ROUNDROBIN | { HASH ( column_name [,...] ) } } ] [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ] [ COMMENT [=] 'text' ]; |
- 其中列约束column_constraint为:
1 2 3 4 5 6 7 8 9
[ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | COMMENT 'text' | UNIQUE index_parameters | PRIMARY KEY index_parameters } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
- 其中列的压缩可选项compress_mode为:
1
{ DELTA | PREFIX | DICTIONARY | NUMSTR | NOCOMPRESS }
- 其中表约束table_constraint为:
1 2 3 4 5 6
[ CONSTRAINT constraint_name ] { CHECK ( expression ) | UNIQUE ( column_name [, ... ] ) index_parameters | PRIMARY KEY ( column_name [, ... ] ) index_parameters | PARTIAL CLUSTER KEY ( column_name [, ... ] ) } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
- 其中like选项like_option为:
1
{ INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | DISTRIBUTION | DROPCOLUMNS | ALL }
- 其中索引参数index_parameters为:
1
[ WITH ( {storage_parameter = value} [, ... ] ) ]
参数说明
- UNLOGGED
如果指定此关键字,则创建的表为非日志表。在非日志表中写入的数据不会被写入到预写日志中,这样就会比普通表快很多。但是非日志表在冲突、执行操作系统重启、强制重启、切断电源操作或异常关机后会被自动截断,会造成数据丢失的风险。非日志表中的内容也不会被复制到备服务器中。在非日志表中创建的索引也不会被自动记录。
使用场景:非日志表不能保证数据的安全性,用户应该在确保数据已经做好备份的前提下使用,例如系统升级时进行数据的备份。
故障处理:当异常关机等操作导致非日志表上的索引发生数据丢失时,用户应该对发生错误的索引进行重建。
UNLOGGED表无主备机制,在系统故障或异常断点等情况下,会有数据丢失风险,不可用来存储基础数据。
- GLOBAL | LOCAL
创建临时表时可以在TEMP或TEMPORARY前指定GLOBAL或LOCAL关键字。目前这两个关键字的设立,仅是为了兼容SQL标准,实际上无论指定GLOBAL还是LOCAL,GaussDB(DWS)都会创建本地临时表。
- TEMPORARY | TEMP
如果指定TEMP或TEMPORARY关键字,则创建的表为临时表。临时表只在当前会话可见,本会话结束后会自动删除。因此,在除当前会话连接的CN以外的其他CN故障时,仍然可以在当前会话上创建和使用临时表。由于临时表只在当前会话创建,对于涉及对临时表操作的DDL语句,会产生DDL失败的报错。因此,建议DDL语句中不要对临时表进行操作。TEMP和TEMPORARY等价。
- 临时表通过每个会话独立的以pg_temp开头的schema来保证只对当前会话可见,因此,不建议用户在日常操作中手动删除以pg_temp,pg_toast_temp开头的schema。
- 如果建表时不指定TEMPORARY/TEMP关键字,而指定表的schema为当前会话的pg_temp_开头的schema,则此表会被创建为临时表。
- IF NOT EXISTS
指定IF NOT EXISTS时,若不存在同名表,则可以成功创建表。若已存在同名表,创建时不会报错,仅会提示该表已存在并跳过创建。
- table_name
要创建的表名。
表名长度不超过63个字符,以字母或下划线开头,可包含字母、数字、下划线、$、#。
使用双引号括起来的表名可以包含空格和特殊字符,但不建议在表名中使用这些字符,因为这样可能会使表名难以引用和使用,而且不同的数据库兼容模式下可能对于这种表名的处理方式也有所不同。
- column_name
新表中要创建的字段名。
字段名长度不超过63个字符,以字母或下划线开头,可包含字母、数字、下划线、$、#。
- data_type
字段的数据类型。
在兼容Teradata或MySQL语法的数据库中,字段数据类型指定为DATE时同样返回为DATE类型,否则返回TIMESTAMP类型。
- compress_mode
表字段的压缩选项,当前仅对行存表有效。该选项指定表字段优先使用的压缩算法。
该压缩选项与列存表自适应压缩算法无关,后者为列存表内部数据存储采用的压缩算法,不支持用户指定压缩方式,详见COMPRESSION参数说明。
取值范围:DELTA、PREFIX、DICTIONARY、NUMSTR、NOCOMPRESS- DELTA压缩仅支持长度为1-8字节的数据类型(0 < pg_type.typlen<=8)。
- PREFIX、NUMSTR压缩仅支持变长数据类型(pg_type.typlen=-1)和NULL结尾的C字符串(pg_type.typlen=-2)。
- COLLATE collation
COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。
- LIKE source_table [ like_option ... ]
LIKE子句声明一个表,新表自动从这个表中继承所有字段名及其数据类型和非空约束。
新表与源表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中,并且也不可能在扫描源表的时候包含新表的数据。
被复制的列和约束并不使用相同的名字进行融合。如果明确的指定了相同的名字或者在另外一个LIKE子句中,将会报错。
- 源表上的字段缺省表达式只有在指定INCLUDING DEFAULTS时,才会复制到新表中。缺省是不包含缺省表达式的,即新表中的所有字段的缺省值都是NULL。
- 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时,会复制到新表中,而其他类型的约束永远不会复制到新表中。非空约束总是复制到新表中。此规则同时适用于表约束和列约束。
- 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。
- 如果指定了INCLUDING STORAGE,则复制列的STORAGE设置会复制到新表中,默认情况下不包含STORAGE设置。
- 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释会复制到新表中。默认情况下,不复制源表的注释。
- 如果指定了INCLUDING PARTITION,则源表的分区定义会复制到新表中,同时新表将不能再使用PARTITION BY子句。默认情况下,不复制源表的分区定义。
- 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。
- 如果指定了INCLUDING DISTRIBUTION,则源表的分布信息会复制到新表中,包括分布类型和分布列,同时新表将不能再使用DISTRIBUTE BY子句。默认情况下,不复制源表的分布信息。
- 如果指定了INCLUDING DROPCOLUMNS,则源表被删除的列信息会被复制到新表中。默认情况下,不复制源表的删除列信息。
- INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS、INCLUDING DISTRIBUTION和INCLUDING DROPCOLUMNS的内容。
- 如果指定了EXCLUDING,则表示不包括指定的参数。
- 如果是OBS冷热表,INCLUDING PARTITION后新表所有分区均为本地热分区。
- 如果源表包含serial、bigserial、smallserial类型,或者源表字段的默认值是Sequence,且Sequence属于源表(通过CREATE SEQUENCE ... OWNED BY创建),这些Sequence不会关联到新表中,新表中会重新创建属于自己的Sequence。这和之前版本的处理逻辑不同。如果用户希望源表和新表共享Sequence,需要首先创建一个共享的Sequence(避免使用OWNED BY),并配置为源表字段默认值,这样创建的新表会和源表共享该Sequence。
- 不建议将其他表私有的Sequence配置为源表字段的默认值,尤其是其他表只分布在特定的NodeGroup上,这可能导致CREATE TABLE ... LIKE执行失败。另外,如果源表配置其他表私有的Sequence,当该表删除时Sequence也会连带删除,这样源表的Sequence将不可用。如果用户希望多个表共享Sequence,建议创建共享的Sequence。
- WITH ( { storage_parameter = value } [, ... ] )
这个子句为表或索引指定一个可选的存储参数。
使用任意精度类型Numeric定义列时,建议指定精度p以及刻度s。在不指定精度和刻度时,会按输入的显示出来。
参数的详细描述如下所示。
- FILLFACTOR
一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是合适的选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。
取值范围:10~100
- ORIENTATION
指定表数据的存储方式,即行存方式、列存方式,该参数设置成功后就不再支持修改。
取值范围:
- ROW,表示表的数据将以行式存储。
- COLUMN,表示表的数据将以列式存储。
默认值:ROW,即行存方式。
- COMPRESSION
指定表数据的压缩级别,它决定了表数据的压缩比以及压缩时间。一般来讲,压缩级别越高,压缩比也越大,压缩时间也越长;反之亦然。实际压缩比取决于加载的表数据的分布特征。
取值范围:
列存表的有效值为YES/NO和LOW/MIDDLE/HIGH,默认值为LOW。当设置为YES时,压缩级别默认为LOW。- 暂不支持行存表压缩功能。
- ORC格式迁移到GaussDB(DWS)列存表,如果使用low级别压缩,单副本大小大约是ORC的1.5~2倍;如果使用high级别压缩,单副本大小基本与ORC持平,在新建GaussDB(DWS)集群规模时,需考虑该转换关系。
- 列存middle压缩固定使用字典压缩,对于数据特征不适合字典压缩的数据,使用middle压缩的结果可能比low压缩更大。
GaussDB(DWS)内部提供如下压缩算法。
表1 列存压缩算法 COMPRESSION
NUMERIC
STRING
INT
LOW
delta压缩+RLE压缩
lz4压缩
delta压缩(RLE可选)
MIDDLE
delta压缩+RLE压缩+lz4压缩
dict压缩或lz4压缩
delta压缩或lz4压缩(RLE可选)
HIGH
delta压缩+RLE压缩+zlib压缩
dict压缩或zlib压缩
delta压缩或zlib压缩(RLE可选)
- COMPRESSLEVEL
指定表数据同一压缩级别下的不同压缩水平,它决定了同一压缩级别下表数据的压缩比以及压缩时间。对同一压缩级别进行了更加详细的划分,为用户选择压缩比和压缩时间提供了更多的空间。总体来讲,此值越大,表示同一压缩级别下压缩比越大,压缩时间越长;反之亦然。该参数只对列存表有效。
取值范围:0~3,默认值为0。
- TTL
设置分区表定时删除分区task任务。默认不创建删除分区task任务。
取值范围:1 hour ~ 100 years
- PERIOD
设置分区表定时创建分区task任务。如果设置TTL,PERIOD不能大于TTL。
取值范围:1 hour ~ 100 years
默认值:1 day
- MAX_BATCHROW
指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。
取值范围:10000~60000
默认值:60,000
- PARTIAL_CLUSTER_ROWS
指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。
取值范围:600000~2147483647
默认值:4,200,000
- enable_delta
默认值:off
- DELTAROW_THRESHOLD
指定列存表导入时小于多少行的数据进入delta表,只在表级参数enable_delta开启时生效。该参数只对列存表有效。
取值范围:0~60000,默认值为6000
- COLVERSION
取值范围:
1.0:列存表的每列以一个单独的文件进行存储,文件名以relfilenode.C1.0、relfilenode.C2.0、relfilenode.C3.0等命名。
2.0:列存表的每列合并存储在一个文件中,文件名以relfilenode.C1.0命名。
默认值:2.0
需注意,OBS冷热表仅支持COLVERSION为2.0格式。
- 8.1.0集群版本该参数默认值为1.0,8.1.1及以上集群版本该参数默认值为2.0,若集群版本由8.1.0升级至8.1.1或以上版本,该参数默认值也会由1.0变为2.0。
- 在建列存表时,选择COLVERSION=2.0,相比于1.0存储格式,在以下场景中性能有明显提升:
- 创建列存宽表场景下,建表时间显著减少。
- roach备份数据场景下,备份时间显著减少。
- build、catch up耗时显著减少。
- 占用磁盘空间大小显著减少。
- SKIP_FPI_HINT
顺序扫描过程中,若需要写FPW(full page writes)日志时,该参数控制是否跳过设置HintBits操作。
默认值:false设置SKIP_FPI_HINT=true时,在对某表执行checkpoint操作后,若对该表进行顺序扫描,将不再产生Xlog。适用于查询次数较少的中间表,有效减少Xlog的大小,提升查询性能。
- FILLFACTOR
- ON COMMIT { PRESERVE ROWS | DELETE ROWS }
ON COMMIT选项决定在事务中执行创建临时表操作,当事务提交时,此临时表的后续操作。
- PRESERVE ROWS(缺省值):提交时不对临时表做任何操作,临时表及其表数据保持不变。
- DELETE ROWS:提交时删除临时表中数据。
- COMPRESS | NOCOMPRESS
创建新表时,需要在CREATE TABLE语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。
缺省值:NOCOMPRESS,即不对元组数据进行压缩。
- DISTRIBUTE BY
指定表如何在节点之间分布或者复制。
取值范围:
- REPLICATION:表的每一行存在所有数据节点(DN)中,即每个数据节点都有完整的表数据。
- ROUNDROBIN:表的每一行被依次发送给各个DN,在这种分布策略下可以保证数据分布不会存在倾斜,但是因为数据分布节点是随机的,导致这类表在计算时会更大概率的触发此表的重分布。各列倾斜都比较严重的大表推荐使用此种分布策略。(ROUNDROBIN仅8.1.2及以上版本支持)
- HASH (column_name ) :对指定的列进行Hash,通过映射,把数据分布到指定DN。
- 当指定DISTRIBUTE BY HASH (column_name)参数时,创建主键和唯一索引必须包含“ column_name”列。
- 当被参照表指定DISTRIBUTE BY HASH (column_name)参数时,参照表的外键必须包含“ column_name”列。
- 如果TO GROUP指定为复制表节点组(8.1.2及以上版本支持),DISTRIBUTE BY必须指定为REPLICATION。如果没有指定DISTRIBUTE BY,创建的表会自动设置为复制表。
- 实时数仓(单机部署)由于只有单DN,因此分布规则会被忽略,也不支持针对分布规则的修改。
默认值:由GUC参数default_distribution_mode控制。- 当default_distribution_mode=roundrobin时,DISTRIBUTE BY的默认值按如下规则选取:
- 若建表时包含主键/唯一约束,则选取HASH分布,分布列为主键/唯一约束对应的列。
- 若建表时不包含主键/唯一约束,则选取ROUNDROBIN分布。
- 当default_distribution_mode=hash时,DISTRIBUTE BY的默认值按如下规则选取:
- 若建表时包含主键/唯一约束,则选取HASH分布,分布列为主键/唯一约束对应的列。
- 若建表时不包含主键/唯一约束,但存在数据类型支持作分布列的列,则选取HASH分布,分布列为第一个数据类型支持作分布列的列。
- 若建表时不包含主键/唯一约束,也不存在数据类型支持作分布列的列,选取ROUNDROBIN分布。
以下数据类型支持作为分布列:- INTEGER TYPES:TINYINT,SMALLINT,INT,BIGINT,NUMERIC/DECIMAL
- CHARACTER TYPES:CHAR,BPCHAR,VARCHAR,VARCHAR2,NVARCHAR2,TEXT
- DATE/TIME TYPES:DATE,TIME,TIMETZ,TIMESTAMP,TIMESTAMPTZ,INTERVAL,SMALLDATETIME
在建表时,选择分布列和分区键可对SQL查询性能产生重大影响。因此,需要根据一定策略选择合适的分布列和分区键。
- 选择合适的分布列
对于采用散列(Hash)方式的数据分布表,一个合适的分布列应将一个表内的数据,均匀分散存储在多个DN内,避免出现数据倾斜现象(即多个DN内数据分布不均)。请按照如下原则判定合适的分布列:
- 判断是否已发生数据倾斜现象。
连接数据库,执行如下语句,查看各DN内元组数目。命令中的斜体部分tablename,请填入待分析的表名。
SELECT a.count,b.node_name FROM (SELECT count(*) AS count,xc_node_id FROM tablename GROUP BY xc_node_id) a, pgxc_node b WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC;
如果各DN内元组数目相差较大(如相差数倍、数十倍),则表明已发生数据倾斜现象,请按照下面原则调整分布列。
- 重新选择分布列,可通过ALTER TABLE语句调整分布列,选择原则如下:
分布列的列值应比较离散,以便数据能够均匀分布到各个DN。例如,考虑选择表的主键为分布列,如在人员信息表中选择身份证号码为分布列。
在满足上面原则的情况下,考虑选择查询中的连接条件为分布列,以便Join任务能够下推到DN中执行,且减少DN之间的通信数据量。
- 如果找不到一个合适的分布列,使数据能够均匀分布到各个DN,那么可以考虑使用REPLICATION或ROUNDROBIN的数据分布方式。由于REPLICATION的数据分布方式会在每个DN中存放完整的数据,因此在表较大且找不到合适的分布列时,推荐使用ROUNDROBIN的数据分布方式。(ROUNDROBIN分布方式8.1.2及以上版本支持)
- 判断是否已发生数据倾斜现象。
- 选择合适的分区键
数据分区功能,可根据表的一列或者多列,将要插入表的记录分为若干个范围(这些范围在不同的分区里没有重叠)。然后为每个范围创建一个分区,用来存储相应的数据。
调整分区键,使每次查询结果尽可能存储在相同或者最少的分区内(称为“分区剪枝”),通过获取连续I/O大幅度提升查询性能。
实际业务中,经常将时间作为查询对象的过滤条件,因此,可考虑选择时间列为分区键,键值范围可根据总数据量、一次查询数据量调整。
- TO { GROUP groupname | NODE ( nodename [, ... ] ) }
TO GROUP指定创建表所在的Node Group,目前不支持hdfs表使用。TO NODE主要供内部扩容工具使用,一般用户不应该使用。
在逻辑集群模式下,如果不指定TO GROUP,表默认会创建在逻辑集群用户关联的节点组中;如果用户没有管理逻辑集群(例如管理员用户或其他普通用户),表默认会创建在第一个逻辑集群中(pgxc_group中oid最小的逻辑集群是第一个逻辑集群)。
如果TO GROUP指定的节点组是复制表节点组,表将创建在所有CN和DN节点上,但复制表数据将只分布在复制表节点组包含的DN节点上。
- COMMENT [=] 'text'
COMMENT子句可在创建表时指定表注释。
- CONSTRAINT constraint_name
列约束或表约束的名字。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。
定义约束有两种方法:
- 列约束:作为一个列定义的一部分,仅影响该列。
- 表约束:不和某个列绑在一起,可以作用于多个列。
- NOT NULL
字段值不允许为NULL。
- NULL
字段值允许为NULL ,这是缺省值。
这个子句只是为和非标准SQL数据库兼容。不建议使用。
- CHECK ( expression )
CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。
声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。
expression表达式中,如果存在“<>NULL”或“!=NULL”,这种写法是无效的,需要写成“is NOT NULL”。
- DEFAULT default_expr
DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式(不允许使用子查询和对本表中的其他字段的交叉引用)。缺省表达式的数据类型必须和字段类型匹配。
缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。
- COMMENT 'text'
COMMENT子句可以指定列的注释。
- UNIQUE index_parameters
UNIQUE ( column_name [, ... ] ) index_parameters
UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。
对于唯一约束,NULL被认为是互不相等的。
如果没有声明DISTRIBUTE BY REPLICATION,则唯一约束的列集合中必须包含分布列。
- PRIMARY KEY index_parameters
PRIMARY KEY ( column_name [, ... ] ) index_parameters
主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。
一个表只能声明一个主键。
如果没有声明DISTRIBUTE BY REPLICATION,则主键约束的列集合中必须包含分布列。
- DEFERRABLE | NOT DEFERRABLE
这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,只有行存的UNIQUE约束和主键约束可以接受这个子句。所有其他约束类型都是不可推迟的。
- PARTIAL CLUSTER KEY
局部聚簇存储,列存表导入数据时按照指定的列(单列或多列),进行局部排序。
- INITIALLY IMMEDIATE | INITIALLY DEFERRED
如果约束是可推迟的,则这个子句声明检查约束的缺省时间。
- 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它;
- 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。
约束检查的时间可以用SET CONSTRAINTS命令修改。
示例
为表定义唯一列约束:
1 2 3 4 5 6 7 8 9 10 11 |
DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE CUSTOMER ( C_CUSTKEY BIGINT NOT NULL CONSTRAINT C_CUSTKEY_pk PRIMARY KEY , C_NAME VARCHAR(25) , C_ADDRESS VARCHAR(40) , C_NATIONKEY INT , C_PHONE CHAR(15) , C_ACCTBAL DECIMAL(15,2) ) DISTRIBUTE BY HASH(C_CUSTKEY); |
为表定义主键表约束,可以在表的一列或多列上定义主键表约束:
1 2 3 4 5 6 7 8 9 10 11 12 |
DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE CUSTOMER ( C_CUSTKEY BIGINT , C_NAME VARCHAR(25) , C_ADDRESS VARCHAR(40) , C_NATIONKEY INT , C_PHONE CHAR(15) , C_ACCTBAL DECIMAL(15,2) , CONSTRAINT C_CUSTKEY_KEY PRIMARY KEY(C_CUSTKEY,C_NAME) ) DISTRIBUTE BY HASH(C_CUSTKEY,C_NAME); |
定义CHECK列约束:
1 2 3 4 5 6 7 8 9 |
DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE CUSTOMER ( C_CUSTKEY BIGINT NOT NULL CONSTRAINT C_CUSTKEY_pk PRIMARY KEY , C_NAME VARCHAR(25) , C_ADDRESS VARCHAR(40) , C_NATIONKEY INT NOT NULL CHECK (C_NATIONKEY > 0) ) DISTRIBUTE BY HASH(C_CUSTKEY); |
定义CHECK表约束:
1 2 3 4 5 6 7 8 9 10 |
DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE CUSTOMER ( C_CUSTKEY BIGINT NOT NULL CONSTRAINT C_CUSTKEY_pk PRIMARY KEY , C_NAME VARCHAR(25) , C_ADDRESS VARCHAR(40) , C_NATIONKEY INT , CONSTRAINT C_CUSTKEY_KEY2 CHECK(C_CUSTKEY > 0 AND C_NAME <> '') ) DISTRIBUTE BY HASH(C_CUSTKEY); |
创建列存表指定存储格式和压缩方式:
1 2 3 4 5 6 7 8 9 10 11 12 |
DROP TABLE IF EXISTS customer_address; CREATE TABLE customer_address ( ca_address_sk INTEGER NOT NULL , ca_address_id CHARACTER(16) NOT NULL , ca_street_number CHARACTER(10) , ca_street_name CHARACTER varying(60) , ca_street_type CHARACTER(15) , ca_suite_number CHARACTER(10) ) WITH (ORIENTATION = COLUMN, COMPRESSION=HIGH,COLVERSION=2.0) DISTRIBUTE BY HASH (ca_address_sk); |
使用DEFAULT为列W_STATE声明默认值:
1 2 3 4 5 6 7 8 9 10 11 |
DROP TABLE IF EXISTS warehouse_t; CREATE TABLE warehouse_t ( W_WAREHOUSE_SK INTEGER NOT NULL, W_WAREHOUSE_ID CHAR(16) NOT NULL, W_WAREHOUSE_NAME VARCHAR(20) UNIQUE DEFERRABLE, W_WAREHOUSE_SQ_FT INTEGER , W_COUNTY VARCHAR(30) , W_STATE CHAR(2) DEFAULT 'GA', W_ZIP CHAR(10) ); |
以like方式创建一个表CUSTOMER_bk:
1 2 |
DROP TABLE IF EXISTS CUSTOMER_bk; CREATE TABLE CUSTOMER_bk (LIKE CUSTOMER INCLUDING ALL); |