#CREATE TABLE

# 通用描述

CREATE TABLE语句用于创建一个表对象,包括HEAP表、TAC表和LSC表:

  • HEAP Table:行存表,采用段页式结构。

  • TAC Table (Transaction Analytics Columnar Table) :列存表,采用段页式结构。

  • LSC Table (Large-scale Storage Columnar Table):列存表,通过列存结构组织数据。

YashanDB通过配置参数DEFAULT_TABLE_TYPE的值(HEAP/TAC/LSC)指定创建表对象时的默认表类型,该参数支持在线切换。同时,YashanDB支持通过ORGANIZATION语法在创建表对象时将其指定为任意的表类型。

分布式部署中不支持HEAP表,该语句还可以指定分布表(Sharded Table)和复制表(Duplicated Table)两种分布类型,默认创建分布表。

共享集群部署中只支持HEAP Table,不支持TAC/LSC/Sharded/Duplicated table。

表类型在创建表对象时被指定,且创建后不可变更。

需注意的是,由于LSC表的对象存储属性,其所在表空间必须已挂载bucket(数据桶),而SYSTEM表空间默认无此设置,因此在系统用户(如SYS)下无法创建LSC表,除非通过ALTER TABLESPACE语句为SYSTEM表空间增加bucket。

Note

在企业生产环境中,一般并不建议在SYSTEM表空间和SYS用户下创建业务表,而应该为其创建单独的表空间和普通用户。

YashanDB中,通过CREATE USER语句创建的普通用户,其默认所属表空间已挂载bucket,可在该用户下创建LSC表。

# 语句定义

create table::=

syntax
CREATE GLOBAL PRIVATE TEMPORARY SHARDED DUPLICATED TABLE IF NOT EXISTS schema . table_name ( relation_properties ) table_properties lsc_table_properties row_movement_clause

relation_properties::=

syntax
column_definition out_of_line_constraint ,

out_of_line_constraint定义

column_definition::=

syntax
column dataType DEFAULT default_expr codec_expr inline_constraint

codec_expr::=

syntax
compression_clause encoding_clause

compression_clause::=

syntax
COMPRESSION compression_type HIGH MEDIUM LOW

compression_type::=

syntax
lz4

encoding_clause::=

syntax
ENCODING PLAIN RLE DICTIONARY ( RLE PLAIN , CARDINALITY ) BYTE-PACKED

inline_constraint定义

table_properties::=

syntax
organization_clause temp_table_attr_clause physical_attribute_clause table_partition_clause lob_clauses logging_clause parallel_clause cache_clause readonly_clause inmemory_clause table_compression nested_table_clauses

organization_clause::=

syntax
ORGANIZATION HEAP TAC LSC

temp_table_attr_clause::=

syntax
ON COMMIT DROP PRESERVE DEFINITION DELETE PRESERVE ROWS

physical_attribute_clause::=

syntax
TABLESPACE tablespace TABLESPACE SET tablespace_set PCTFREE integer PCTUSED integer INITRANS integer MAXTRANS integer storage_clause deferred_segment_creation

storage_clause定义

deferred_segment_creation::=

syntax
SEGMENT CREATION IMMEDIATE DEFERRED

table_partition_clause::=

syntax
range_partitions list_partitions hash_partitions composite_range_partitions composite_list_partitions composite_hash_partitions consistent_hash_partitions consistent_hash_with_subpartitions

range_partitions::=

syntax
PARTITION BY RANGE ( column , ) interval_clause ( PARTITION partname range_values_clause table_partition_description , )

interval_clause::=

syntax
INTERVAL ( expr ) STORE IN ( tablespace , )

range_values_clause::=

syntax
VALUES LESS THAN ( literal MAXVALUE , )

table_partition_description::=

syntax
TABLESPACE tablespace PCTFREE integer PCTUSED integer INITRANS integer MAXTRANS integer deferred_segment_creation

list_partitions::=

syntax
PARTITION BY LIST ( column , ) ( PARTITION partname list_values_clause table_partition_description , )

list_values_clause::=

syntax
VALUES ( DEFAULT list_values )

list_values::=

syntax
literal NULL , ( literal NULL , ) ,

hash_partitions::=

syntax
PARTITION BY HASH ( column , ) individual_partition_clause hash_partitions_by_quantity

individual_partition_clause::=

syntax
( PARTITION partname partition_storage_clause , )

partition_storage_clause::=

syntax
TABLESPACE tablespace

hash_partitions_by_quantity::=

syntax
PARTITIONS hash_partition_quantity STORE IN ( tablespace , ) OVERFLOW STORE IN ( tablespace , )

composite_range_partitions::=

syntax
PARTITION BY RANGE ( column , ) subpartition_by_range subpartition_by_list subpartition_by_hash ( range_partition_desc , )

subpartition_by_range::=

syntax
SUBPARTITION BY RANGE ( column , ) subpartition_template

subpartition_template::=

syntax
SUBPARTITION TEMPLATE ( range_subpartition_desc , list_subpartition_desc , individual_hash_subparts , )

range_subpartition_desc::=

syntax
SUBPARTITION subpartname range_values_clause TABLESPACE tablespace deferred_segment_creation

list_subpartition_desc::=

syntax
SUBPARTITION subpartname list_values_clause TABLESPACE tablespace deferred_segment_creation

individual_hash_subparts::=

syntax
SUBPARTITION subpartname TABLESPACE tablespace deferred_segment_creation

subpartition_by_list::=

syntax
SUBPARTITION BY LIST ( column , ) subpartition_template

subpartition_by_hash::=

syntax
SUBPARTITION BY HASH ( column , ) subpartition_template hash_subparts_by_quantity

hash_subparts_by_quantity::=

syntax
SUBPARTITIONS integer STORE IN ( tablespace , )

range_partition_desc::=

syntax
PARTITION partname range_values_clause table_partition_description hash_subparts_by_quantity ( range_subpartition_desc , list_subpartition_desc , individual_hash_subparts , )

composite_list_partitions::=

syntax
PARTITION BY LIST ( column , ) subpartition_by_range subpartition_by_list subpartition_by_hash ( list_partition_desc , )

list_partition_desc::=

syntax
PARTITION partname list_values_clause table_partition_description hash_subparts_by_quantity ( range_subpartition_desc , list_subpartition_desc , individual_hash_subparts , )

composite_hash_partitions::=

syntax
PARTITION BY HASH ( column , ) subpartition_by_range subpartition_by_list subpartition_by_hash ( hash_partition_desc , ) hash_partitions_by_quantity

hash_partition_desc::=

syntax
PARTITION partname table_partition_description ( range_subpartition_desc , list_subpartition_desc , individual_hash_subparts , )

consistent_hash_partitions::=

syntax
PARTITION BY CONSISTENT HASH ( column , ) individual_partition_clause hash_partitions_by_quantity

consistent_hash_with_subpartitions::=

syntax
PARTITION BY CONSISTENT HASH ( column , ) subpartition_by_range subpartition_by_list subpartition_by_hash ( hash_partition_desc , ) hash_partitions_by_quantity

lob_clauses::=

syntax
lob_clause

lob_clause::=

syntax
LOB ( column , ) STORE AS BASICFILE SECUREFILE ( TABLESPACE space_name ENABLE DISABLE STORAGE IN ROW )

logging_clause::=

syntax
LOGGING NOLOGGING

parallel_clause::=

syntax
NOPARALLEL PARALLEL integer

cache_clause::=

syntax
CACHE NOCACHE

readonly_clause::=

syntax
READONLY READWRITE

inmemory_clause::=

syntax
INMEMORY NO INMEMORY

table_compression::=

syntax
COMPRESS NOCOMPRESS

nested_table_clauses::=

syntax
nested_table_clause

nested_table_clause::=

syntax
NESTED TABLE nested_item COLUMN_VALUE LOCAL GLOBAL STORE AS storage_table ( nested_table_clause ) ( TABLESPACE tablespace_name )

lsc_table_properties::=

syntax
compression_clause table_sort_clause mcol_ttl_clause storage_table

table_sort_clause::=

syntax
ORDER BY ( column_name , ) NULLS FIRST LAST ASC DESC SCOL

mcol_ttl_clause::=

syntax
MCOL TTL timestamp

row_movement_clause::=

syntax
ENABLE DISABLE ROW MOVEMENT

# global temporary

该语句只作用于单机HEAP/TAC表,用于指定创建的表为全局临时表。全局临时表对数据库所有会话(Session)可见,但表中数据在各会话间隔离,即每个会话只能看到在本会话中插入的数据。

全局临时表被创建后将一直存在(除非被DROP),ON COMMIT DELETE | PRESERVE ROWS则定义了其数据在事务提交后是否保留,具体在temp_table_attr_clause中说明。

示例

CREATE GLOBAL TEMPORARY TABLE globaltemtable(c1 INT,c2 INT);

# private temporary

该语句只作用于单机HEAP/TAC表,用于指定创建的表为私有临时表。在某个会话中创建的私有临时表,其表结构及数据只对本会话可见。

私有临时表的数据在当前会话中一直保留,且不会在事务提交时被删除,ON COMMIT DROP | PRESERVE DEFINITION则定义了事务提交后是否DROP该表,具体在temp_table_attr_clause中说明。

私有临时表的名称必须为YAS$PTT_开头,而对于其他类型的表,其表名称则不允许以YAS$PTT_开头。

示例

CREATE PRIVATE TEMPORARY TABLE YAS$PTT_privatetemtable(c1 INT,c2 INT);

--如不以YAS$PTT_开头会返回错误
CREATE PRIVATE TEMPORARY TABLE privatetemtable(c1 INT,c2 INT);
YAS-02170 create a private temporary table with a name not matching 'YAS$PTT_' prefix

# sharded

该语句只在分布式部署中使用,表示创建一张分布表,分布表在每个数据节点上依据Chunk将数据分片存储。

YashanDB将分布表的每一个分区(Partition)作为一个Chunk,插入表中的数据将按照指定的规则被分配到各个Chunk中,可通过consistent_hash_partitions语句定义这种规则,不指定规则时,将对表按如下规则进行哈希分区来分片存储数据:

  • 如果表上定义了主键列,则分区键列为主键列。
  • 如果表上未定义主键列,但存在唯一索引, 则分区键为所有唯一索引的公共子集中首个恰当数据类型的字段。
  • 否则, 分区键为表的首个恰当数据类型的列字段。

SHARDED为YashanDB分布式数据库的默认建表方式,即CREATE TABLE=CREATE SHARDED TABLE。

示例

--创建默认的分布表并插入记录
CREATE SHARDED TABLE area_shard
(area_no CHAR(2) NOT NULL,
area_name VARCHAR2(60),
DHQ VARCHAR2(20) DEFAULT 'ShenZhen' NOT NULL);

--查询表属性,sharded=Y表示为分布表
SELECT table_name,table_type,partitioned,SHARDED,DUPLICATED 
FROM USER_TABLES 
WHERE table_name='AREA_SHARD';
TABLE_NAME                 TABLE_TYPE PARTITIONED SHARDED DUPLICATED
-------------------------- ---------- ----------- ------- ----------
AREA_SHARD                 LSC        N           Y       N

--查询分布表信息
SELECT table_name,dist_type,dist_key_count FROM USER_DIST_TABLES 
WHERE table_name='AREA_SHARD';
TABLE_NAME               DIST_TYPE     DIST_KEY_COUNT
------------------------ ------------- --------------
AREA_SHARD               HASH                       1

--查询默认的分区键
SELECT name,column_name,column_position 
FROM USER_DIST_KEY_COLUMNS 
WHERE name='AREA_SHARD';
NAME               COLUMN_NAME       COLUMN_POSITION
------------------ ----------------- ---------------
AREA_SHARD         AREA_NO                         0

--查询表分区数量,即Chunk数量
SELECT COUNT(1) 
FROM USER_TAB_PARTITIONS 
WHERE table_name='AREA_SHARD';
             COUNT(1)
---------------------
                    6

# duplicated

该语句只在分布式部署中使用,表示创建一张复制表,插入表中的数据将被完全复制到各个数据节点中。

示例

--创建复制表
CREATE DUPLICATED TABLE area_dupli
(area_no CHAR(2) NOT NULL,
area_name VARCHAR2(60),
DHQ VARCHAR2(20) DEFAULT 'ShenZhen' NOT NULL);
 
--查询表属性,duplicated=Y表示为复制表
SELECT table_name,table_type,partitioned,SHARDED,DUPLICATED 
FROM USER_TABLES 
WHERE table_name='AREA_DUPLI';
TABLE_NAME                 TABLE_TYPE PARTITIONED SHARDED DUPLICATED
-------------------------- ---------- ----------- ------- ----------
AREA_DUPLI                 LSC        N           N       Y

# if not exists

该语句用于在CREATE表之前,先判断该表是否存在,省略则不会判断。若不省略,此时如果要创建的表已存在,系统将不会报错,并且使用旧表,不会创建新的表。

示例

--创建已存在的表area时,不会报错,且新表未创建成功
CREATE TABLE IF NOT EXISTS area(c1 INT, c2 INT);

SELECT * FROM area WHERE area_no='01';
AREA_NO AREA_NAME        DHQ       
------- ---------------- ----------
01      华东           Shanghai    

# table_name

该语句用于指定创建的表的名称,不可省略,且需符合YashanDB的对象命名规范

如表名称里出现了.符号,表示该符号之前为用户名、之后为表名,此时必须拥有在指定用户名下创建表对象的权限。

# relation_properties

该语句用于指定创建的表的结构,包括列字段(Column)和约束(Constraint)。

# column_definition

该语句用于定义表的列字段项。

# column

列字段的名称,不可省略,且需符合YashanDB的对象命名规范

# datatype

指定列字段的数据类型。查看YashanDB的数据类型描述

其中,数据类型指定为LOB/JSON类型时,可通过lob_clauses子句指定其存储属性。

数据类型指定为Nested Table UDT类型时,必须通过nested_table_clauses子句创建嵌套表,且不能为临时表的列字段指定Nested Table UDT类型。

# default default_expr

列字段的缺省值。default_expr可以为字面量、运算式、函数等表达式。

# codec_expr

对于LSC表的列字段,使用本语句定义列字段的编码压缩属性,系统按此设置存储该列上的数据。 对于单机TAC表的列字段,使用本语句定义列字段的字典编码属性,系统按此设置存储该列上的数据。

# compression_clause

该语句用于对于LSC表定义压缩属性。

compression_type

  • 压缩算法:采用当前流行的LZ4压缩算法。

  • 压缩级别:可指定按LOW、MEDIUM、HIGN三个级别进行压缩 ,未指定级别时,默认按LOW级别压缩。

YashanDB支持按表级别或列级别定义压缩属性,并提供如下配置参数用于设置系统默认的压缩属性:

  • COMPRESSION:是否进行数据压缩。
  • COMPRESSION_LEVEL:数据压缩的级别。

对于某一个列上的数据,基于表列级别定义的压缩属性与系统默认的压缩属性之间的优先关系如下:

  • 如果在该列上定义了压缩属性,则采用该列上的压缩属性进行数据存储。
  • 如果该列上没有定义,而在表上定义了压缩属性,则采用表上的压缩属性进行数据存储。
  • 如果该列和表上均未定义,则采用系统默认的压缩属性进行数据存储。

# encoding_clause

对于LSC表的列定义编码属性,指定按如下一种方式进行编码:

  • PLAIN编码:即不编码,按原始方式存储数据。
  • RLE编码:游程长度编码。
  • DICTIONARY(PLAIN):字典编码后的数据进行PLAIN编码。
  • DICTIONARY(RLE):字典编码后的数据进行RLE编码。
  • BYTE-PACKED:根据数据字节长度编码。

对于某一个列上的数据,是否应该编码和采用何种编码方式,与该列的数据类型和数据特点相关,如下为YashanDB对不同数据类型可适配的编码方式(✓表示适配,X表示不适配):

数据类型 PLAIN编码 RLE编码 字典编码 BYTE-PACKED编码
TINYINT/SMALLINT/大对象型 X X X
INT/BIGINT/FLOAT/DOUBLE/日期型 X
字符型 X X
NUMBER型 X X

其中,BOOLEAN类型数据由系统自动进行布尔编码存储,无需为其指定编码方式。长度大的CHAR字段采用字典编码对内存占用比较大,对于超过128字节的CHAR类型,请尽量不要选择字典编码。

示例

--创建LSC表,压缩指定列且对其字典编码存储
DROP TABLE IF EXISTS finance_info;
CREATE TABLE finance_info
(year CHAR(4) NOT NULL COMPRESSION lz4 HIGH ENCODING DICTIONARY(RLE),
month CHAR(2) NOT NULL,
branch CHAR(4),
revenue_total NUMBER(10,2),
cost_total NUMBER(10,2),
fee_total NUMBER(10,2)
);

对于TAC表的列定义字典编码属性,指定按DICTIONARY(PLAIN)方式进行编码,该属性仅支持数据类型为字符型的列使用。 同时TAC表的列使用该属性支持指定字典值上限,规格为[1,65535],缺省默认字典值上限为65535。

示例

--创建TAC表,对指定列字典编码存储且指定字典上限为100
DROP TABLE IF EXISTS finance_info;
CREATE TABLE finance_info
(year CHAR(4) NOT NULL ENCODING DICTIONARY(PLAIN, 100),
month CHAR(2) NOT NULL,
branch CHAR(4),
revenue_total NUMBER(10,2),
cost_total NUMBER(10,2),
fee_total NUMBER(10,2)
);

# inline_constraint

该语句用于定义表的行内约束项。关于约束项的详细描述请参考通用SQL语法constraint

其中,不能为临时表建立FOREIGN KEY约束,也不能为其他表建立到临时表的FOREIGN KEY约束。

# out_of_line_constraint

该语句用于定义表的行外约束项。关于约束项的详细描述请参考通用SQL语法constraint

其中,不能为临时表建立FOREIGN KEY约束,也不能为其他表建立到临时表的FOREIGN KEY约束。

# table_properties

该语句用于指定创建的表的各项属性,多项间以空格进行分隔。

# organization_clause

该语句指定表的数据存储方式(表类型),可省略,则系统按DEFAULT_TABLE_TYPE参数的值创建相应类型的表。YashanDB针对不同表类型的数据存储方式参考产品描述存储架构

HEAP

创建HEAP行存表。

TAC

创建TAC列存表。

LSC

创建LSC列存表,此种表类型要求默认或指定表空间为databucket表空间,否则创建失败。

示例

CREATE TABLE area_tac
(area_no CHAR(2) NOT NULL,
area_name VARCHAR2(60),
DHQ VARCHAR2(20) DEFAULT 'ShenZhen' NOT NULL)
ORGANIZATION TAC;

# temp_table_attr_clause

该语句只针对全局临时表和私有临时表,且DELETE|PRESERVE ROWS只可用于全局临时表,而DROP|PRESERVE DEFINITION只可用于私有临时表。

# on commit delete|preserve rows

指定事务提交后在当前会话中插入的全局临时表的数据是否保留,DELETE为删除,PRESERVE为保留。

示例

--创建全局临时表T_orders_info,并指定PRESERVE ROWS
CREATE GLOBAL TEMPORARY TABLE T_orders_info (
order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10))
ON COMMIT PRESERVE ROWS;
  
--插入数据并提交
INSERT INTO T_orders_info VALUES ('20010102020001','product 001','02','0202',SYSDATE-400,'0001');
COMMIT;
  
--查询结果,由于指定了PRESERVE ROWS,则仍可以查询到数据(且只为本会话插入的数据),如为DELETE ROWS则无法查询到数据
SELECT * FROM T_orders_info;
ORDER_NO          ORDER_DESC     AREA  BRANCH ORDER_DATE             SALESPERSON 
----------------- -------------- ----- ------ ---------------------- -------------
20010102020001    product 001    02    0202   2020-12-06 22:55:32    0001
# on commit drop|preserve definition

指定事务提交后在当前会话中创建的私有临时表是否被删除,DROP为删除,PRESERVE为保留。

示例

--创建私有临时表PTT_orders_info,并指定DROP DEFINITION
CREATE PRIVATE TEMPORARY TABLE YAS$PTT_orders_info (
order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10))
ON COMMIT DROP DEFINITION;
  
--插入数据并提交
INSERT INTO YAS$PTT_orders_info VALUES ('20010102020001','product 001','02','0202',SYSDATE-400,'0001');
COMMIT;
  
--查询结果,由于指定了DROP DEFINITION,事务提交后PTT_orders_info表被删除
SELECT * FROM YAS$PTT_orders_info;
[1:14]YAS-02010 table or view SALES.YAS$PTT_ORDERS_INFO not found

# physical_attribute_clause

该语句用于指定创建的表的物理存储属性或创建表时是否立即创建segment。

# tablespace tablespace_name

该语句用于指定表所在的表空间。

对于临时表,只能指定一个temporary类型的表空间,省略则默认为表所属用户所在的表空间(临时表的表空间默认为数据库创建时生成的temporary表空间)。

对于LOB型的列字段,行外存储的LOB列数据表空间默认与表所在表空间一致,也可以单独指定。

对于LSC表,为其所指定的表空间必须拥有bucket属性,详见CREATE TABLESPACE描述。其中,系统的缺省表空间(DEFAULT表空间)已默认拥有bucket属性,可以作为LSC表的表空间。

分布式部署中,创建分布表时不能使用本语句指定表空间。

# tablespace set tablespace_set_name

指定分布表所在的表空间集。省略时则默认为内置的USERS表空间集。

# pctfree/pctused/initrans/maxtrans

指定表的PCTFREE/PCTUSED/INITRANS/MAXTRANS属性,省略则默认为8/NULL/2/255。

其中:

  • PCTFREE:表示数据块为数据库对象进行UPDATE保留的空间百分比,当可用空间低于该百分比时无法进行INSERT,只能进行UPDATE。
  • PCTUSED:表示数据块为数据库对象保留的最小已用空间百分比,当数据所占空间低于该百分比时可进行INSERT。
  • INITRANS:表示每个数据块中初始并发事务项的数量。
  • MAXTRANS:表示每个数据块中并发事务项数量的最大值。
# storage_clause

指定为表分配的初始空间和最大空间大小,由于YashanDB采取延迟分配的策略(有数据才分配空间),不建议指定此参数。

# deferred_segment_creation
# segment creation deferred|immediate

用于指定创建表对象时,segment的创建方式是立即创建或延迟创建,临时表不支持该语法。

IMMEDIATE指立即创建,DEFERRED指延迟创建,若省略,默认为延迟创建。

示例

CREATE TABLE employee_info (
name CHAR(10) NOT NULL,
age INT,
id INT NOT NULL
)TABLESPACE users PCTFREE 50 PCTUSED 20 INITRANS 3 MAXTRANS 254 SEGMENT CREATION DEFERRED;

# table_partition_clause

该语句用于为表创建分区(Partition)或者组合分区,可通过USER_TAB_PARTITIONS和USER_TAB_SUBPARTITIONS视图查看所有分区和子分区信息。

现支持range-range、range-list、range-hash、list-range、list-list、list-hash、hash-range、hash-list、hash-hash组合分区,暂不支持interval-range、interval-list、interval-hash组合分区。

该语句包含如下限制:

# range_partitions

创建范围分区,分区列为多项时以,分隔。

如果指定了INTERVAL,那么分区列的数量必须为1,并且只能是数值或者时间类型。

# interval_clause

创建INTERVAL类型的范围分区。

INTERVAL(expr)

范围分区根据分区界值将每个分区定义了下限值(即为前一分区的上限值)和上限值(分区界值),最后的一个分区其上限值即为最大的分区界值。指定INTERVAL表示,当要插入的数据超过最大分区界值时,系统将根据如下规则创建一个新分区,并将这行数据插入到新分区中:

  • 新分区由系统自动命名。
  • 新分区的上限值=最大分区界值+INTERVAL值,之后新分区的上限值将成为最大分区界值。
  • 如果最大分区界值已被定义为MAXVALUE,则无法创建新分区,该数据无法插入表。
  • expr为表达式,表达式的结果类型需与分区列字段的数据类型一致。

此时,如表上已建立了分区索引(Local Partitioned Index),则系统在创建新分区的同时,也会创建相应的索引分区。

STORE IN

为INTERVAL分区指定表空间,指定多个表空间以,分隔,则系统在创建新分区时,按照此处定义的顺序,循环使用作为新分区的表空间。未指定本语句时分区的表空间默认为表所在的表空间。

示例

--创建范围分区表orders_info,并指定INTERVAL值
DROP TABLE IF EXISTS orders_info;
CREATE TABLE orders_info (order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10),
id NUMBER)
TABLESPACE yashan
PARTITION BY RANGE (id)
INTERVAL (1000)
(PARTITION p_orders_info_1 VALUES LESS THAN (800));
  
--插入三条数据均成功,如未指定INTERVAL值,则只有第一条数据可以插入成功
INSERT INTO orders_info VALUES ('20010102020001','product 001','02','0201',SYSDATE-400,'0001',300);
INSERT INTO orders_info VALUES ('20010102020001','product 001','02','0201',SYSDATE-400,'0001',2000);
INSERT INTO orders_info VALUES ('20010102020001','product 001','02','0201',SYSDATE-400,'0001',20000);
COMMIT;
  
--查询该表上的分区,除p_orders_info_1 分区外,系统自动创建了另外两个分区
SELECT TABLE_NAME t_name,TABLESPACE_NAME ts_name,PARTITION_NAME par_name,HIGH_VALUE par_max FROM USER_TAB_PARTITIONS WHERE TABLE_NAME='ORDERS_INFO';
T_NAME             TS_NAME   PAR_NAME         PAR_MAX  
----------------- ---------- ---------------- ---------
ORDERS_INFO       YASHAN     SYS_P22          20800    
ORDERS_INFO       YASHAN     SYS_P21          2800     
ORDERS_INFO       YASHAN     P_ORDERS_INFO_1  800   

--创建分区键为时间类型的INTERVAL范围分区表
DROP TABLE IF EXISTS orders_info;
CREATE TABLE orders_info (order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10),
id NUMBER)
PARTITION BY RANGE (order_date)
INTERVAL (INTERVAL '3' month)
(PARTITION p_firstquarter VALUES LESS THAN (DATE '2000-01-01'));

# range_values_clause

定义范围分区的上限值。

literal

分区列为多项时,则此处的上限值用,分隔并与分区列一一对应。

MAXVALUE

MAXVALUE表示无上限,即超过前一分区的上限的所有数据均进入此分区中,包括NULL。如所有分区列都定义了以MAXVALUE作为上限值的分区,不支持再继续定义MAXVALUE分区。

在定义了MAXVALUE的分区后,不能通过ADD PARTITION语句增加新的分区,仅能通过SPLIT PARTITION语句将已存在分区划分成新的分区。

示例

DROP TABLE IF EXISTS orders_maxvalue;
CREATE TABLE orders_maxvalue(
order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10),
id NUMBER)
PARTITION BY RANGE(id)
(PARTITION p_orders_max_1 VALUES LESS THAN (800),
 PARTITION p_orders_max_2 VALUES LESS THAN (1000),
 PARTITION p_orders_max_3 VALUES LESS THAN (1500),
 PARTITION p_orders_max_4 VALUES LESS THAN (MAXVALUE)
);

--创建分区列为多项的范围分区表
DROP TABLE IF EXISTS orders_multikey;
CREATE TABLE orders_multikey(
order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10),
id NUMBER)
PARTITION BY RANGE(id,order_date)
(PARTITION p_orders_max_1 VALUES LESS THAN (800,'2010-01-01'),
 PARTITION p_orders_max_2 VALUES LESS THAN (1000,'2010-05-01'),
 PARTITION p_orders_max_3 VALUES LESS THAN (1500,'2010-10-01')
);

--所有分区列均定义MAXVALUE分区后继续定义MAXVALUE分区,此时返回错误
DROP TABLE IF EXISTS orders_multimax;
CREATE TABLE orders_multimax(
order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10),
id NUMBER)
PARTITION BY RANGE(id,order_date)
(PARTITION p_orders_max_1 VALUES LESS THAN (800,'2010-01-01'),
 PARTITION p_orders_max_2 VALUES LESS THAN (1000,'2010-05-01'),
 PARTITION p_orders_max_3 VALUES LESS THAN (1500,'2010-10-01'),
 PARTITION p_orders_max_4 VALUES LESS THAN (MAXVALUE,'2010-10-01'),
 PARTITION p_orders_max_5 VALUES LESS THAN (MAXVALUE,MAXVALUE),
 PARTITION p_orders_max_6 VALUES LESS THAN (MAXVALUE,MAXVALUE)
);

YAS-04240 partition bound is too high

# table_partition_description

定义范围分区的存储属性。

TABLESPACE tablespace_name

为分区指定一个表空间,省略则默认为表所在的表空间。

PCTFREE/PCTUSED/INITRANS/MAXTRANS

指定PCTFREE/PCTUSED/INITRANS/MAXTRANS属性,省略则默认为8/NULL/2/255。

各属性定义同physical_attribute_clause语句中描述一致。

deferred_segment_creation

SEGMENT CREATION DEFERRED|IMMEDIATE

用于指定创建表对象时,segment的创建方式是立即创建或延迟创建,临时表不支持该语法。

IMMEDIATE指立即创建,DEFERRED指延迟创建,若省略,默认为延迟创建。

示例

--单机部署中创建定义了存储属性的范围分区
DROP TABLE IF EXISTS sales_info_range;
CREATE TABLE sales_info_range
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4),
 product CHAR(5),
 quantity NUMBER DEFAULT 0 NOT NULL,
 amount NUMBER(10,2) DEFAULT 0 NOT NULL,
 salsperson CHAR(10))
PARTITION BY RANGE(year)
(PARTITION p_sales_info_range_1 VALUES LESS THAN('2011') PCTFREE 3 SEGMENT CREATION DEFERRED,
 PARTITION p_sales_info_range_2 VALUES LESS THAN('2021'),
 PARTITION p_sales_info_range_3 VALUES LESS THAN('2031'));

# list_partitions

创建列表分区,分区列为多项时以,分隔。

# list_values_clause

定义列表分区的列表内容。

DEFAULT

DEFAULT表示将在已定义列表值之外的所有数据均进入此分区中,如不指定DEFAULT分区,插入已定义列表值之外的所有数据会报错。如指定,须作为最后一个分区指定,且DEFAULT分区不支持指定多次。

在定义了DEFAULT的分区后,不能通过ADD PARTITION语句增加新的分区,仅能通过SPLIT PARTITION语句将已存在分区划分成新的分区。

list_values

分区列为多项时,须用,分隔并与分区列一一对应,该列表内容须指定为字面量或NULL。

# table_partition_description

范围分区描述一致。

示例

--创建列表分区的销售信息表
DROP TABLE IF EXISTS sales_info;
CREATE TABLE sales_info
(year CHAR(4) NOT NULL,
month CHAR(2) NOT NULL,
branch CHAR(4) NOT NULL,
product CHAR(10) NOT NULL,
quantity NUMBER DEFAULT 0 NOT NULL,
amount NUMBER(10,2) DEFAULT 0 NOT NULL,
salsperson CHAR(10))
PARTITION BY LIST(year,month)
(PARTITION p_sales_info1_1 VALUES (('2018','01'),('2018','02')),
PARTITION p_sales_info1_2 VALUES ('2020','01'),
PARTITION p_sales_info1_3 VALUES (DEFAULT));

# hash_partitions

创建哈希分区,分区列为多项时以,分隔,哈希分区有如下两种创建方式:

  • 逐个指定哈希分区。
  • 使用hash分数批量指定哈希分区。

# individual_partition_clause

本语句用于逐个指定哈希分区,对每个分区分别定义其名称和存储属性,分区之间用,分隔。

partition_storage_clause

定义哈希分区的存储属性。

TABLESPACE tablespace_name

为分区指定一个表空间,省略则默认为表所在的表空间。

示例

DROP TABLE IF EXISTS sales_info_hash;
CREATE TABLE sales_info_hash
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4),
 product CHAR(5),
 quantity NUMBER DEFAULT 0 NOT NULL,
 amount NUMBER(10,2) DEFAULT 0 NOT NULL,
 salsperson CHAR(10))
PARTITION BY HASH(year)
(PARTITION p_sales_info_hash_1,
 PARTITION p_sales_info_hash_2);
 
--单机部署中为分区指定表空间,分布式部署中不支持此操作
DROP TABLE IF EXISTS sales_info_hashpar;
CREATE TABLE sales_info_hashpar
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4))
PARTITION BY HASH(year)
(PARTITION p_sales_info_hash_1 TABLESPACE users,
 PARTITION p_sales_info_hash_2);

# hash_partitions_by_quantity

本语句用于按hash分数批量指定哈希分区,所有分区名称由系统生成。

hash_partition_quantity

表示hash分区的数量。

STORE IN

STORE IN子句描述哈希分区所属的表空间,表空间可指定多个,且数量不需要与分区的数量一致, 系统将按本语句中表空间指定的顺序进行循环归属。

不指定本语句时,系统默认使用表所在的表空间作为所有分区的表空间。

示例

--单机部署中通过hash分数创建哈希分区表,并指定STORE IN语句
DROP TABLE IF EXISTS sales_info_hash;
CREATE TABLE sales_info_hash
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4),
 product CHAR(5),
 quantity NUMBER DEFAULT 0 NOT NULL,
 amount NUMBER(10,2) DEFAULT 0 NOT NULL,
 salsperson CHAR(10))
PARTITION BY HASH(year)
PARTITIONS 4
STORE IN (ts1,ts2);

# composite_range_partitions

定义范围分区的组合分区,每个范围分区下可以定义范围、列表、哈希三种子分区的一种。

# subpartition_by_range

定义范围子分区的分区列或子分区模板。

# range_partition_desc

创建范围分区及其子分区。

# range_subpartition_desc

具体定义一个范围子分区表空间和segment是否立即创建的属性。

range_values_clause

定义范围分区的上限值。

literal

分区列为多项时,则此处的上限值用,分隔并与分区列一一对应。

MAXVALUE

MAXVALUE表示无上限,即超过前一分区的上限的所有数据均进入此分区中,包括NULL。如所有分区列都定义了以MAXVALUE作为上限值的分区,不支持再继续定义MAXVALUE分区。在定义了MAXVALUE的分区后,不能再增加新的分区。

deferred_segment_creation

SEGMENT CREATION IMMEDIATE|DEFERRED

用于指定创建表对象时,segment的创建方式是立即创建或延迟创建,临时表不支持该语法。

IMMEDIATE指立即创建,DEFERRED指延迟创建,若省略,默认为延迟创建。

示例

-- range-hash组合分区
CREATE TABLE rh_composite(a INT, b INT)
PARTITION BY RANGE(a)
SUBPARTITION BY HASH(b)
(
PARTITION p1 VALUES LESS than(1) (SUBPARTITION sp1, SUBPARTITION sp2),
PARTITION p2 VALUES LESS than(2) (SUBPARTITION sp3, SUBPARTITION sp4)
);
-- range-list组合分区
CREATE TABLE rl_composite(a INT, b INT)
PARTITION BY RANGE(a)
SUBPARTITION BY LIST(b)
(
PARTITION p1 VALUES LESS than(1) (SUBPARTITION sp1 VALUES(10), SUBPARTITION sp2 VALUES(20)),
PARTITION p2 VALUES LESS than(2) (SUBPARTITION sp3 VALUES(10), SUBPARTITION sp4 VALUES(20))
);
-- range-range组合分区
CREATE TABLE rr_composite(a INT, b INT)
PARTITION BY RANGE(a)
SUBPARTITION BY RANGE(b)
(
PARTITION p1 VALUES LESS than(1) (SUBPARTITION sp1 VALUES LESS than(10), SUBPARTITION sp2 VALUES LESS than(20)),
PARTITION p2 VALUES LESS than(2) (SUBPARTITION sp3 VALUES LESS than(10), SUBPARTITION sp4 VALUES LESS than(20))
);

# composite_list_partitions

定义列表分区的组合分区,每个列表分区下可以定义范围、列表、哈希三种子分区的一种。

# subpartition_by_list

定义列表子分区的分区列或子分区模板。

# list_partition_desc

创建列表分区及其子分区。

# list_subpartition_desc

具体定义一个列表子分区的表空间和segment是否立即创建的属性。

# list_values_clause

定义列表分区的列表内容。

DEFAULT

DEFAULT表示将在已定义列表值之外的所有数据均进入此分区中,如不指定DEFAULT分区,插入已定义列表值之外的所有数据会报错。如指定,须作为最后一个分区指定,且DEFAULT分区不支持指定多次。在定义了DEFAULT的分区后,不能再增加新的分区。

list_values

分区列为多项时,须用,分隔并与分区列一一对应,该列表内容须指定为字面量或NULL。

deferred_segment_creation

用于指定创建表对象时,segment的创建方式是立即创建或延迟创建,临时表不支持该语法。

IMMEDIATE指立即创建,DEFERRED指延迟创建,若省略,默认为延迟创建。

示例

-- list-hash组合分区
CREATE TABLE lh_composite(a INT, b VARCHAR(10))
PARTITION BY LIST(a)
SUBPARTITION BY HASH(b)
subpartitions 8
(PARTITION p1 VALUES(10), PARTITION p2 VALUES(DEFAULT));
-- list-list组合分区
CREATE TABLE ll_composite(a INT, b INT)
PARTITION BY LIST(a)
SUBPARTITION BY LIST(b)
(
PARTITION p1 VALUES(1) (SUBPARTITION sp1 VALUES(1), SUBPARTITION sp2 VALUES(2)),
PARTITION p2 VALUES(2) (SUBPARTITION sp3 VALUES(1), SUBPARTITION sp4 VALUES(2))
);
-- list-range组合分区
CREATE TABLE lr_composite(a INT, b INT)
PARTITION BY LIST(a)
SUBPARTITION BY RANGE(b)
(
PARTITION p1 VALUES(1) (SUBPARTITION sp1 VALUES LESS than(10), SUBPARTITION sp2 VALUES LESS than(20)),
PARTITION p2 VALUES(2) (SUBPARTITION sp3 VALUES LESS than(10), SUBPARTITION sp4 VALUES LESS than(20))
);

# composite_hash_partitions

定义哈希分区的组合分区,每个哈希分区下可以定义范围、列表、哈希三种子分区的一种。

# subpartition_by_hash

定义哈希子分区的分区列或子分区模板,也可以指定子分区分区数量。

# hash_partition_desc

创建哈希分区及其子分区。

# individual_hash_subparts

定义一个哈希子的表空间和segment是否立即创建的属性。

deferred_segment_creation

用于指定创建表对象时,segment的创建方式是立即创建或延迟创建,临时表不支持该语法。

IMMEDIATE指立即创建,DEFERRED指延迟创建,若省略,默认为延迟创建。

# hash_subparts_by_quantity

使用hash分数批量定义哈希子分区。

示例

-- hash-hash组合分区
CREATE TABLE hh_composite(a INT, b VARCHAR(10))
PARTITION BY HASH(a)
SUBPARTITION BY HASH(b)
subpartitions 8
(PARTITION p1, PARTITION p2);
-- hash-list组合分区
CREATE TABLE hl_composite(c1 INT, c2 VARCHAR(10))
PARTITION BY HASH(c1)
SUBPARTITION BY LIST(c2)
(
PARTITION p1(SUBPARTITION sp1 VALUES('a')), 
PARTITION p2 (SUBPARTITION sp3 VALUES('d'), SUBPARTITION sp4 VALUES(DEFAULT))
);
-- hash-range组合分区
CREATE TABLE hl_composite(a INT, b INT, c INT,d INT)
PARTITION BY HASH(a)
SUBPARTITION BY RANGE(b,c,d)
(
PARTITION p1 (SUBPARTITION sp1 VALUES LESS than(10,20,30), SUBPARTITION sp2 VALUES LESS than(20,20,30)),
PARTITION p2
);

# subpartition_template

定义子分区模板,支持RANGE、LIST及HASH三种类型。

执行本语句可为分区批量创建相同定义的子分区,避免冗杂操作。当组合分区表的某个分区没有定义子分区,则使用子分区模板为默认子分区定义。

执行本语句时须为子分区定义名称,否则返回错误。通过子分区模板创建的子分区名为分区名_子分区名,可通过DBA_TAB_SUBPARTITIONS视图查看所有子分区信息。

示例

-- 定义range子分区模板
CREATE TABLE hr_composite(a INT, b VARCHAR(10))
PARTITION BY HASH(a)
SUBPARTITION BY RANGE(b)
SUBPARTITION template (SUBPARTITION sub1 VALUES LESS than ('a') , SUBPARTITION sub2 VALUES LESS than (MAXVALUE))
(PARTITION p1,PARTITION p2);
-- 定义list子分区模板
CREATE TABLE hl_composite(a INT, b VARCHAR(10)) 
PARTITION BY HASH(a) SUBPARTITION BY LIST(b)
SUBPARTITION template(SUBPARTITION sp1 VALUES('a'), SUBPARTITION sp2 VALUES(DEFAULT))
partitions 8;
-- 定义hash子分区模板
CREATE TABLE hh_composite(a INT, b VARCHAR(10))
PARTITION BY HASH(a)
SUBPARTITION BY HASH(b)
SUBPARTITION template (SUBPARTITION sp1 TABLESPACE SYSTEM, SUBPARTITION sp2 TABLESPACE users)
(PARTITION p1, PARTITION p2);
--仅部分定义了子分区,其余通过子分区模板自行创建子分区
CREATE TABLE hl_partcomposite(c1 INT,c2 INT)
PARTITION BY HASH(c1)
SUBPARTITION BY LIST(c2)
SUBPARTITION template(SUBPARTITION sp9 VALUES(2))
(PARTITION p1 (SUBPARTITION sp11 VALUES(1)),
 PARTITION p2,
 PARTITION p3);

# consistent_hash_partitions

该语句仅可用于为分布表创建分区,即表示建立分布表的数据分片(Chunk)规则。

# consistent

本关键字可省略,表示为分布表所创建分区必须指定为一致性哈希分区。

# column

指定分区键对应的列,包含多个列时以,分隔。分布表的数据分片规则即为按此分区键对应的列或列组合进行哈希分配。

YashanDB对分区键存在如下约束要求:

  • 列需符合类型要求,不支持为LOB、JSON、RAW、ST_GEOMETRY、ROWID及UROWID类型。
  • 如果表上定义了主键列,则分区键必须为主键列的其中一项或多项。
  • 如果表上未定义主键列,则分区键可以为任意项。
# individual_partition_clause

本语句用于逐个指定哈希分区,语法定义与单机部署中的individual_partition_clause类似,但不可以指定表空间属性,即在定义分布表的分区时,分区只能使用表所在的表空间。

使用本方法逐个指定分区时,需注意指定的分区数量必须与当前分布式部署环境中的Chunk总数量完全一致,否则返回错误。

# hash_partitions_by_quantity

本语句用于按hash分数批量指定哈希分区,语法定义与单机部署中的hash_partitions_by_quantity类似,但不可以指定表空间属性,即在定义分布表的分区时,分区只能使用表所在的表空间。

hash_partition_quantity

表示hash分区的数量,可以指定为AUTO关键字或者任意数值。

如指定为AUTO关键字,系统将依据Chunk总数量自动生成hash分区,且hash分区的数量与Chunk总数量一致。

如指定为数值,当该数值不等于当前分布式部署环境中的Chunk总数量时,系统将依据Chunk总数量自动生成hash分区,且hash分区的数量与Chunk总数量一致。

Note

Chunk总数量可由建库参数USERS_DATASPACE_SCALE_OUT_FACTOR * 当前DN组个数计算得到结果,其中,建库参数USERS_DATASPACE_SCALE_OUT_FACTOR在安装过程中配置且后续不可修改,可咨询数据库管理员获得该参数的值。

示例

--重新创建销售信息表,且要求按年和月的组合哈希分配数据到各节点中(以Chunk总数量为7为例)
DROP TABLE IF EXISTS sales_info;
CREATE TABLE sales_info
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4),
 product CHAR(5),
 quantity NUMBER DEFAULT 0 NOT NULL,
 amount NUMBER(10,2) DEFAULT 0 NOT NULL,
 salsperson CHAR(10))
PARTITION BY CONSISTENT HASH (year,month) 
(PARTITION p1,PARTITION p2,PARTITION p3,PARTITION p4,PARTITION p5,PARTITION p6,PARTITION p7);
 
INSERT INTO sales_info VALUES ('2001','01','0201','11001',30,500,'0201010011');
INSERT INTO sales_info VALUES ('2015','11','0101','11001',20,300,'');
INSERT INTO sales_info VALUES ('2021','10','0101','11001',20,300,'');
INSERT INTO sales_info VALUES ('2000','12','0102','11001',20,300,'');
INSERT INTO sales_info VALUES ('2015','03','0102','11001',20,300,'');
INSERT INTO sales_info VALUES ('2021','05','0101','11001',40,600,'');
COMMIT;

--通过AUTO关键字指定hash分区数量
DROP TABLE IF EXISTS sales_info;
CREATE TABLE sales_info
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4),
 product CHAR(5),
 quantity NUMBER DEFAULT 0 NOT NULL,
 amount NUMBER(10,2) DEFAULT 0 NOT NULL,
 salsperson CHAR(10))
PARTITION BY CONSISTENT HASH (year,month) 
PARTITIONS AUTO;

--通过数值指定hash分区数量
DROP TABLE IF EXISTS sales_info;
CREATE TABLE sales_info
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4),
 product CHAR(5),
 quantity NUMBER DEFAULT 0 NOT NULL,
 amount NUMBER(10,2) DEFAULT 0 NOT NULL,
 salsperson CHAR(10))
PARTITION BY CONSISTENT HASH (year,month) 
PARTITIONS 7;

--按分区检索sales_info数据
SELECT year,month,product,amount
FROM sales_info PARTITION (p1);
YEAR  MONTH PRODUCT        AMOUNT
----- ----- --------- -----------
2000  12    11001             300
2015  03    11001             300

# consistent_hash_with_subpartitions

该语句用于为分布表创建哈希分区的组合分区,仅适用于分布式部署。

除不支持为分区指定表空间属性外,本语句语法同composite_hash_partitions描述。

示例

--重建上例中的sales_info表,为其中一个分区创建range子分区
DROP TABLE IF EXISTS sales_info;
CREATE TABLE sales_info
(year CHAR(4) NOT NULL,
 month CHAR(2) NOT NULL,
 branch CHAR(4),
 product CHAR(5),
 quantity NUMBER DEFAULT 0 NOT NULL,
 amount NUMBER(10,2) DEFAULT 0 NOT NULL,
 salsperson CHAR(10))
PARTITION BY CONSISTENT HASH (year,month) 
SUBPARTITION BY RANGE(quantity)
(
PARTITION p1 (SUBPARTITION sp1 VALUES LESS than(30), SUBPARTITION sp2 VALUES LESS than(60)),
    PARTITION p2,PARTITION p3,PARTITION p4,PARTITION p5,PARTITION p6
);

INSERT INTO sales_info VALUES ('2001','01','0201','11001',10,500,'0201010011');
INSERT INTO sales_info VALUES ('2015','11','0101','11001',20,300,'');
INSERT INTO sales_info VALUES ('2021','10','0101','11001',30,300,'');
INSERT INTO sales_info VALUES ('2000','12','0102','11001',40,300,'');
INSERT INTO sales_info VALUES ('2015','03','0102','11001',50,300,'');
INSERT INTO sales_info VALUES ('2021','05','0101','11001',60,600,'');
COMMIT;

--按组合分区检索sales_info数据
SELECT year,month,product,quantity,amount
FROM sales_info SUBPARTITION (sp2);
YEAR  MONTH PRODUCT      QUANTITY      AMOUNT
----- ----- --------- ----------- -----------
2000  12    11001              40         300
2015  03    11001              50         300

# lob_clause

该语句用于指定LOB/JSON类型列字段的存储属性,同时指定多列用,分隔。

# basicfile|securefile

该语句用于语法兼容,无实际含义。

# tablespace

指定LOB/JSON数据进行行外存储时的表空间,不指定该属性时LOB/JSON数据存储在表所在表空间中。

# disable storage in row

指定对于LOB/JSON列字段,无论其大小,都执行行外存储,即为其创建新的存储空间,而不是与行中的其他列字段数据存储在一起。

# enable storage in row

指定将LOB/JSON列字段的数据存放在行内空间,即与行中的其他列字段数据存储在一起。但当该数据大小超过一定的行内限制时,即使指定了ENABLE STORAGE IN ROW,仍进行行外存储。对于HEAP表,该限制是4000字节;对于TAC/LSC表,该限制是32000字节。

Note

数据在存储时会产生一些内部元信息,行存表字节限制包括这部分元数据所占空间,列存表则不包括。

示例

--创建一张员工信息表,其中introduce为超长文本的LOB类型字段
CREATE TABLE employees1(area CHAR(2),
branch CHAR(4),
employee_info JSON,
introduce CLOB)
LOB(introduce,employee_info) STORE AS (TABLESPACE yashan ENABLE STORAGE IN ROW);
  
--插入两行数据,其中第一行数据里的introduce因为数据长度小于3988字节,采用的是行内存储,而第二行数据则采用的是行外存储,json字段长度小于3988字节,采用的是行内存储。
INSERT INTO employees1 VALUES ('04','0401',
JSON('{"employee_no":"0401010008","employee_name":"Sam1","sex":"1","entire_date":"SYSDATE-3"}'),
'深圳计算科学研究院是深圳市人民政府2018年11月批准建设的十大基础研究机构之一');
INSERT INTO employees1 VALUES ('04','0401',
JSON('{"employee_no":"0401010008","employee_name":"Sam2","sex":"1","entire_date":"SYSDATE-3"}'),
LPAD('深圳',4000,'深圳'));
COMMIT;
 
SELECT JSON_FORMAT(employee_info), LENGTHB(introduce) FROM employees1;
JSON_FORMAT(EMPLOYEE                                                LENGTHB(INTRODUCE) 
---------------------------------------------------------------- --------------------- 
{"sex":"1","employee_no":"0401010008","entire_date":"SYSDATE-3","employee_name":"Sam1"}                   108
{"sex":"1","employee_no":"0401010008","entire_date":"SYSDATE-3","employee_name":"Sam2"}                 12000

# logging_clause

用于指定表的logging属性,默认值为logging,logging描述请参考ALTER TABLE的logging_clause部分。

共享集群部署下不支持nologging。

# parallel_clause

用于指定后续查询创建的表对象时,默认的并行度,语法兼容。

# cache_clause

语法兼容,无实际含义。

# readonly_clause

语法兼容,无实际含义。

# inmemory_clause

语法兼容,无实际含义。

# table_compression

语法兼容,无实际含义。

# nested_table_clause

该语句用于定义和创建嵌套表,YashanDB中的嵌套表被用于实现与含有Nested Table类型的UDT(用户自定义类型)列的存储,详见数据类型中关于用户自定义类型的描述,共享集群部署下不支持嵌套表。

# nested_item

指定嵌套表对应的列字段,或列字段属性(该属性为Nested Table类型)。

# column_value

当出现多层嵌套表(列字段为一个行成员包含Nested Table类型的Nested Table集合)时,对于里层的嵌套表使用COLUMN_VALUE关键字来表示nested_item。

# local|global

当主表为分区表时,使用LOCAL关键字指定嵌套表也为与主表一一对应的分区,使用GLOBAL关键字指定嵌套表不分区,省略关键字时默认为LOCAL。

# storage_table

指定嵌套表的名称,不可省略,且需符合YashanDB的对象命名规范

对于多层嵌套表,在名称后接(nested_table_clause)定义里层的嵌套表信息。

# tablespace

为嵌套表指定独立的表空间,省略时默认嵌套表存储在与主表相同的表空间。

示例

DROP TABLE IF EXISTS area_intro;
DROP TABLE IF EXISTS province_intro;
CREATE OR REPLACE TYPE tb_type AS TABLE OF CHAR(10);
/
CREATE OR REPLACE TYPE obj_type AS OBJECT(city_id INT, branch_list tb_type);
/

--创建单层嵌套表
CREATE TABLE province_intro (id INT, citys tb_type, city_intro obj_type)
NESTED TABLE citys STORE AS nt_province_citys TABLESPACE yashan
NESTED TABLE city_intro.branch_list STORE AS nt_province_branch;

--创建多层嵌套表
CREATE OR REPLACE TYPE tb_type_city AS TABLE OF tb_type;
/
CREATE TABLE area_intro(id INT, provinces tb_type_city)
NESTED TABLE provinces STORE AS nt_area_provinces(
    NESTED TABLE COLUMN_VALUE STORE AS nt_nt_province_citys);

# lsc_table_properties

该语句用于定义LSC表的专有属性,这些属性只可以在创建LSC表时指定,否则报错。

# compression_clause

定义LSC表的压缩属性,同列字段定义的压缩属性描述,系统按此设置对所有列数据进行压缩存储。

# table_sort_clause

本语句用于定义LSC表的排序键,其中排序列可以是表中的任意列(可组合),不指定本语句时,默认以第一列作为排序键,且默认值为NULLS FIRST ASC。

YashanDB在存储LSC表数据时,会自适应的按照一定的排序粒度对存储进行排序。通过本语句所指定的排序键仅作为加速属性使用,即当对表执行查询、更新或删除等操作时,如过滤条件中包含已定义的排序键,系统将在存储层进行排序加速计算,从而获得更优的查询性能。

# column_name

本语句用于指定表的排序列,排序列不支持为如下类型:

  • CLOB
  • BLOB
  • NCLOB
  • BIT
  • ROWID
  • CURSOR
  • JSON
  • UDT
# nulls (first|last)

本语句用于指定空值的排列位置,NULLS FIRST表示空值排列在最前,NULLS LAST表示空值排列在最后。当未指定此语句时,对升序排列缺省为NULLS LAST,对降序排列缺省为NULLS FIRST。

# asc|desc

本语句用于指定排序方式,ASC表示升序,DESC表示降序,省略则默认为升序。

# scol

默认LSC表可变数据(MCOL)也会使用排序键,如可变数据(MCOL)不需要点查加速,在创建时可指定仅针对稳态数据(SCOL)使用排序键,也可以通过ALTER TABLE语句开启或关闭可变数据(MCOL)的排序键。

Note

可变数据的排序键会降低导入性能,生产环境中的存量数据建议先导入然后再打开可变数据的排序键,或直接通过Bulkload模式导入成稳态数据。

示例

--创建LSC表,压缩且按指定列排序存储
DROP TABLE IF EXISTS finance_info;
CREATE TABLE finance_info
(year CHAR(4) NOT NULL,
month CHAR(2) NOT NULL,
branch CHAR(4),
revenue_total NUMBER(10,2),
cost_total NUMBER(10,2),
fee_total NUMBER(10,2)
)
COMPRESSION lz4 HIGH
ORDER BY (year,month,branch);

# mcol_ttl_clause

该语句用于定义LSC表的可变数据最大生命周期。

在YashanDB中,对LSC表插入的数据将先作为可变数据(MCOL)存储,满足一定条件后触发后台线程将可变数据转为稳态数据(SCOL,不可变数据)进入数据桶(bucket,对象存储目录)。

此值保证用户插入数据在可变数据区内至少保留1/2 MCOL TTL时间,最多则保留MCOL TTL时间。

指定了可变数据最大生命周期后,系统将把该值和数据量一起作为触发转换线程的条件,让用户可以根据自身业务情况设定更合理的转换时间。

timestamp

生命周期数值,该值须遵循INTERVAL YEAR TO MONTH或INTERVAL DAY TO SECOND数据类型的格式表述,例如'1' YEAR(9)'30:59.9' MINUTE TO SECOND(6),具体请参考日期型中这两种类型的描述。

示例

--创建可变数据生命周期为1个月的LSC表,即在满1个月时,MCOL数据将被转换为SCOL数据
DROP TABLE IF EXISTS finance_info;
CREATE TABLE finance_info
(year CHAR(4) NOT NULL,
month CHAR(2) NOT NULL,
branch CHAR(4),
revenue_total NUMBER(10,2),
cost_total NUMBER(10,2),
fee_total NUMBER(10,2)
)
COMPRESSION lz4 HIGH
ORDER BY (year,month,branch)
MCOL TTL '1' MONTH;

# row_movement_clause

该语句用于指定创建的表中的行数据是否可以物理移动,HEAP表和TAC表省略则默认为DISABLE ROW MOVEMENT,LSC表省略则默认为ENABLE ROW MOVEMENT。

在YashanDB中,默认行的Rowid是不变化的,但在某些特殊场景,例如对分区表的分区键值进行更新操作,导致其所在行需要从当前分区迁移到另一个分区中,行的Rowid将发生变更,这种变动在表ENABLE ROW MOVEMENT时是被允许的,且YashanDB在此情况下会保证事务的强一致性,避免出现漏更新(lost update)。

开启row movement后,并发事务中可能会触发语句重启(restart statement,回滚之前的操作并重新执行DML事务),影响并发性能 ,因此在正常情况下不建议开启此开关,在可预知会发生行迁移的业务场景中(例如闪回数据),可通过ALTER TABLE语句临时打开,并在结束后关闭。

分布式部署中仅有分区表跨分区更新或LSC表中稳态数据更新时需要ENABLE ROW MOVEMENT,跨分区更新场景中仅DN节点内进行跨分区更新,无法更新分区键。

示例

--创建一张ENABLE ROW MOVEMENT的分区表
DROP TABLE IF EXISTS orders_info_rowmove;
CREATE TABLE orders_info_rowmove (order_no CHAR(14) NOT NULL,
order_desc VARCHAR2(100),
area CHAR(2),
branch CHAR(4),
order_date DATE DEFAULT SYSDATE NOT NULL,
salesperson CHAR(10),
id NUMBER)
PARTITION BY RANGE (id )
(PARTITION p1 VALUES LESS THAN (800),
PARTITION p2 VALUES LESS THAN (1800),
PARTITION p3 VALUES LESS THAN (2800))
ENABLE ROW MOVEMENT;
下载文档
复制链接