#CREATE TABLE

# 通用描述

CREATE TABLE语句用于创建一个表对象,表类型可分为HEAP表、TAC表和LSC表。分布式部署中,本语句还可以指定表对象的分布类型:分布表(Sharded Table)或复制表(Duplicated Table),默认为分布表。

YashanDB支持通过配置DEFAULT_TABLE_TYPE参数(HEAP|TAC|LSC)指定创建表对象时的默认表类型,且该参数允许在线切换。同时,支持通过ORGANIZATION语法在创建表对象时指定其表类型。表对象创建成功后无法再修改表类型。

类型 存储方式 存储结构 适用部署形态
HEAP表 行存 段页式结构
  • 单机部署
  • 共享集群部署
  • LSC表 列存 列存结构
  • 单机部署
  • 分布式部署
  • TAC表 列存 段页式结构
  • 单机部署
  • 分布式部署
  • 在分析业务场景中,推荐使用LSC表。

    创建LSC表前,需确保其所在表空间已挂载bucket(数据桶)。通过CREATE USER语句创建的普通用户默认所属表空间会默认挂载bucket,因此普通用户可直接创建LSC表,而系统用户则因产品架构而异:

    • 单机部署中,由于SYSTEM表空间默认未挂载bucket,系统用户(如SYS)无法直接创建LSC表,需先执行ALTER TABLESPACE语句为SYSTEM表空间挂载bucket再创建LSC表。
    • 分布式部署中,由于系统用户创建的表对象默认在users表空间中且users表空间默认已挂载bucket,无需额外操作即可直接创建LSC表。

    Note

    在实际生产环境中,建议在创建业务表前先为其合理规划表空间和用户,相关语句请查阅CREATE TABLESPACECREATE USER

    # 语句定义

    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 object_table

    relation_properties::=

    syntax
    column_definition out_of_line_constraint ,

    object_table::=

    syntax
    OF schema . object_type

    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 UNCOMPRESSED

    compression_type::=

    syntax
    LZ4 ZSTD

    encoding_clause::=

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

    inline_constraint定义

    table_properties::=

    table_properties
    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 table_encryption_clause

    organization_clause::=

    syntax
    ORGANIZATION HEAP TAC LSC EXTERNAL external_table_clause

    external_table_clause定义

    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 lob_clauses , )

    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 lob_clauses , )

    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 lob_clauses , )

    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 lob_clauses deferred_segment_creation

    list_subpartition_desc::=

    syntax
    SUBPARTITION subpartname list_values_clause TABLESPACE tablespace lob_clauses deferred_segment_creation

    individual_hash_subparts::=

    syntax
    SUBPARTITION subpartname TABLESPACE tablespace lob_clauses 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 CHUNK integer CACHE NOCACHE CACHE READS LOGGING NOLOGGING COMPRESS LOW MEDIUM HIGH NOCOMPRESS DEDUPLICATE KEEP_DUPLICATES )

    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 )

    table_encryption_clause::=

    syntax
    ENCRYPT USING ' AES128 ' ' SM4 '

    lsc_table_properties::=

    syntax
    compression_clause table_sort_clause mcol_ttl_clause transformer_clause storage_table

    table_sort_clause::=

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

    mcol_ttl_clause::=

    syntax
    MCOL TTL timestamp

    transformer_clause::=

    syntax
    ENABLE DISABLE TRANSFORM COMPACT BUILD AC TRANSFORM COMPACT BUILD AC

    row_movement_clause::=

    syntax
    ENABLE DISABLE ROW MOVEMENT

    # global temporary

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

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

    示例(HEAP表和单机TAC表)

    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_ORA$PTT_开头,其他类型的表名称则不允许以YAS$PTT_ORA$PTT_开头。

    私有临时表不允许创建约束。

    示例(HEAP表和单机TAC表)

    CREATE PRIVATE TEMPORARY TABLE YAS$PTT_privatetemtable(c1 INT,c2 INT);
    
    --如不以YAS$PTT_或ORA$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的对象命名规范

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

    # object_table

    通过OF子句显示创建一个object_type对应的对象表。对象表的列和object_type的属性一一对应。

    Caution

    对象表功能属于实验室特性,不推荐在生产环境中使用,以免影响系统稳定性。

    # 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表定义压缩属性。

    • 压缩算法:可指定为LZ4或ZSTD压缩算法,或指定为UNCOMPRESSED不对数据进行压缩。

    • 压缩级别:指定压缩算法为LZ4或ZSTD后,可指定按LOW、MEDIUM、HIGH三个级别进行压缩。若不指定级别,会根据配置项COMPRESSION_LEVEL默认指定。

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

    列级压缩属性 > 表级压缩属性 > 系统参数COMPRESSION与COMPRESSION_LEVEL的相关配置。

    建议您根据数据库的使用场景,选择合适的压缩算法。LZ4压缩算法的优点是:解压与压缩速度快,并且有着较好的压缩效果,ZSTD压缩算法相对于LZ4压缩算法,解压和压缩速度较慢,但是压缩效果更好。

    • 如果您不能确定表的使用场景,推荐您使用系统默认的LZ4 LOW进行压缩,大多数场景下,LZ4可以用较少的CPU资源,减少IO需要时间。
    • 对于有高查询性能要求的场景,建议您使用LZ4进行压缩,压缩等级需要根据您对数据导入和冷热数据转换的性能要求来决定,低压缩等级时数据导入和冷热转换速度更快。
    • 对于归档数据,且查询性能要求较为宽松,建议您使用ZSTD进行压缩,等级可根据您对导入速度的要求进行调整。

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

    compression_type

    该子句用于指定压缩算法及压缩机别。

    • 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表)

    -- 创建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表)

    -- 创建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表空间,否则创建失败。

    # external

    创建外部表,外部表为一种表结构存储在数据库内,而数据存储在数据库外的特殊表类型。由于外部表的数据未存储在数据库内,因此基于行的所有DDL操作,如索引、行迁移、闪回等,均不适用于外部表。

    外部表对应数据只能被查询,不可增删改。

    对于外部表而言,关于segment的属性设置没有意义也不会实际生效。

    创建外部表语句仅适用于单机部署。

    # external_table_clause

    external_table_clause外部表所对应的外部数据结构定义,具体描述参考通用语法EXTERNAL_TABLE

    本语句可省略,若省略则所创建的外部表不指定相应的外部数据结构,该表将无法正常查询。

    示例(单机、分布式部署)

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

    # temp_table_attr_clause

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

    若省略该语句,默认值分别为DELETE ROWS和DROP DEFINITION。

    Note: 当临时表设置了DELETE ROWS属性时,如果先对表进行了插入操作,然后开启自治事务,而且自治事务内进行了提交操作,那么自治事务内插入的数据将不会清理。

    # on commit delete|preserve rows

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

    示例(HEAP表、单机TAC表)

    -- 创建全局临时表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 order_no,order_desc,area,branch,order_date,salesperson 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表示保留。

    示例(单机HEAP表、TAC表)

    -- 创建私有临时表并指定DROP DEFINITION
    CREATE PRIVATE TEMPORARY TABLE YAS$PTT_orders_info (
    order_no CHAR(14),
    order_desc VARCHAR2(100),
    area CHAR(2),
    branch CHAR(4),
    order_date DATE DEFAULT SYSDATE,
    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:15]YAS-02012 table or view does not exist
    

    # physical_attribute_clause

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

    # tablespace tablespace_name

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

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

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

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

    # tablespace set tablespace_set_name

    指定分布表所在的表空间集。省略时,或者指定为 DEFAULT 时,默认为表用户的默认表空间集。若用户未指定默认表空间集,使用内置的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视图查看所有分区和子分区信息。

    创建组合分区时,一级分区不能指定为INTERVAL类型的范围分区(range_partitions)。

    在分布式部署中,该语句只能为复制表创建分区,如需为分布表创建分区,请使用consistent_hash_partitions语句。

    该语句包含如下限制:

    • 不允许为临时表创建分区。
    • 不允许将LOB列/JSON列指定为分区键和子分区键。

    # 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

    physical_attribute_clause语句中SEGMENT CREATION的描述一致。

    示例(单机部署)

    --单机部署中创建定义了存储属性的范围分区
    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 (yashan1,yashan2);
    

    # 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

    physical_attribute_clause语句中SEGMENT CREATION的描述一致。

    示例(单机、共享集群部署)

    -- 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 hr_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视图查看所有子分区信息。

    对于分布表,分区数等同于Chunk数。

    示例(单机、共享集群部署)

    -- 定义range子分区模板
    CREATE TABLE hr_composite_template(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 list_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 hash_composite(a INT, b VARCHAR(10))
    PARTITION BY HASH(a)
    SUBPARTITION BY HASH(b)
    SUBPARTITION template (SUBPARTITION sp1 TABLESPACE yashan1, SUBPARTITION sp2 TABLESPACE yashan2)
    (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总数量为21为例)
    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, 
    PARTITION p8, PARTITION p9, PARTITION p10, PARTITION p11, PARTITION p12, PARTITION p13, PARTITION p14, PARTITION p15, 
    PARTITION p16, PARTITION p17, PARTITION p18, PARTITION p19, PARTITION p20, PARTITION p21);
    
    -- 通过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;
     
    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;
     
    -- 按分区检索sales_info数据
    SELECT year,month,product,amount FROM sales_info PARTITION (SYS_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, PARTITION p7, PARTITION p8, 
    PARTITION p9, PARTITION p10, PARTITION p11, PARTITION p12, PARTITION p13, PARTITION p14, PARTITION p15, PARTITION p16, PARTITION p17, PARTITION p18, PARTITION p19, PARTITION p20, PARTITION p21
    );
    
    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类型列字段的存储属性,同时指定多列用,分隔。

    • KEEP_DUPLICATES/DEDUPLICATE, CHUNK integer, NOCACHE/CACHE, LOGGING/NOLOGGING, NOCOMPRE/COMPRESS(LOW|MEDIUM|HIGH) 等LOB参数仅为语法兼容, tablespace space_name参数在分区LOB以及二级分区LOB的LOB子句中仅为语法兼容。
    • chunk integer中integer取值范围为(0,32K]。
    • hash分区与二级分区的LOB子句仅能指定TABLESPACE space_name参数。
    # 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部分。

    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);
    

    # table_encryption_clause

    该语句用于指定表的加密属性,本语句可省略,省略表示创建的表不加密。

    表加密使用约束如下:

    • sys用户不可进行表加密。
    • 表加密属性一经指定无法修改。
    • 如果同时使用表加密和表空间加密,目标将采用表加密算法。

    ENCRYPT

    对表开启加密功能。指定ENCRYPT时,表示创建加密表。

    USING encryption_algorithm

    该语句用于指定加密算法,支持AES128和SM4,可省略,省略时默认采用AES128算法。

    示例

    -- 创建加密表并指定使用SM4加密算法
    DROP TABLE IF EXISTS encrypt_area;
    CREATE TABLE encrypt_area
    (area_no CHAR(2), 
    area_name VARCHAR2(60), 
    DHQ VARCHAR2(20)) 
    ENCRYPT USING 'SM4';
    
    -- 创建加密表,但不指定加密算法
    DROP TABLE IF EXISTS encrypt_branches;
    CREATE TABLE encrypt_branches
    (branch_no CHAR(4), 
    branch_name VARCHAR2(200), 
    area_no CHAR(2), 
    address VARCHAR2(200)) 
    ENCRYPT;
    

    # 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表)

    --创建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),具体请参考日期时间型中这两种类型的描述。

    示例(LSC表)

    --创建可变数据生命周期为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;
    

    # transformer_clause

    LSC表默认拥有转换、合并和生成AC数据的后台数据转换能力。

    在某些情况下,如果希望建表时就设置某些后台数据转换能力,可以使用此语法进行关闭或打开。建表完成后也可再使用ALTER TABLE语句对后台数据转换能力进行开启或关闭。

    示例(LSC表)

    -- 创建一个关闭合并能力的LSC表
    DROP TABLE IF EXISTS lsc_compact_disable;
    CREATE TABLE lsc_compact_disable(x INT) DISABLE compact;
    

    # 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;
    
    pdf-btn 下载文档
    copy-btn 复制链接