CREATE TABLE语法用来创建Lindorm搜索表。

语法

CREATE TABLE [ IF NOT EXISTS ] table_name
     '('
      column_definition
      ( ',' column_definition )*
       [ ',' PRIMARY KEY '(' primary_key ')' ]
      ')'
     [ PARTITION BY RANGE TIME '(' time_partition_key=value ')' ]
     [ PARTITION BY HASH '(' hash_partition_key (',' hash_partition_key)* ')' ]
     [ PARTITIONS intValue ]
     WITH [ table_options ];
column_definition      ::=  column_name data_type
primary_key            ::=  column_name [ ',' column_name ]
time_partition_key     ::=  column_name
hash_partition_key     ::=  column_name ['(' salt_factor=intValue ')']
说明 创建表语句支持IF NOT EXISTS,其中主键由一个或多个列组合而成。

参数

table_options参数说明如下表:
参数说明
RANGE_TIME_PARTITION_START表示创建索引表操作前几天开始创建分区。适用于有历史数据的场景,如果历史数据的时间戳比开始分区的时间还要小,则会报错。
RANGE_TIME_PARTITION_INTERVAL表示间隔几天创建新分区。例如:RANGE_TIME_PARTITION_INTERVAL='7'表示每隔一周创建一个新分区。
RANGE_TIME_PARTITION_TTL表示保留几天的分区数据。例如:RANGE_TIME_PARTITION_TTL='180'表示保留半年的分区数据,历史分区数据会被自动清理掉。
RANGE_TIME_PARTITION_MAX_OVERLAP如果写入的数据时间点是将来的时间,这个参数表示写入的数据时间点与当前时刻的最大时间间隔,单位为天。
RANGE_TIME_PARTITION_FIELD_TIMEUNIT表示业务指定的时间分区字段单位,默认单位为毫秒(ms)。
  • 时间分区字段单位设置为秒(s),数字长度为10位。
  • 时间分区字段单位设置为毫秒(ms),数字长度为13位。
数据分区参数说明:
  • PARTITION BY RANGE TIME:表示数据按照时间范围分区。
  • PARTITION BY HASH:表示数据按照HASH分区。
  • PARTITIONS intValue:自定义数据的分区数量。

示例

  • 创建表dt。
    CREATE TABLE dt (
      p1 integer, p2 varchar, c1 integer, c2 integer, constraint pk PRIMARY KEY(p1,p2));
  • 对于时间序列的数据,可以按照时间范围分区,例如按照周或者月进行分区,同一时间范围内的数据将会聚集存储,并且历史分区数据会被自动清理掉。
    • 按照业务的时间列orderTime分区,从30天前开始,每7天自动分区,默认保留90天。
      CREATE TABLE dt_partition (
        storeId integer, goodsId varchar, goodsPrice integer, orderTime bigint, constraint pk primary key(storeId))
        PARTITION BY RANGE TIME(orderTime) PARTITIONS 16
        WITH (RANGE_TIME_PARTITION_START='30', RANGE_TIME_PARTITION_INTERVAL='7', RANGE_TIME_PARTITION_TTL='90', RANGE_TIME_PARTITION_MAX_OVERLAP='10');
    • 按照业务的时间列orderTime分区,从半年前开始,每1个月自动分区,默认保留半年,时间分区字段单位设置为秒。
      CREATE TABLE dt_partition (
        storeId integer, goodsId varchar, goodsPrice integer, orderTime bigint, constraint pk primary key(storeId))
        PARTITION BY RANGE TIME(orderTime) PARTITIONS 16
        WITH (RANGE_TIME_PARTITION_START='180', RANGE_TIME_PARTITION_INTERVAL='30', RANGE_TIME_PARTITION_TTL='180', RANGE_TIME_PARTITION_MAX_OVERLAP='10', RANGE_TIME_PARTITION_FIELD_TIMEUNIT='s');
  • HASH分区将数据进行散列存储,从而避免出现数据的热点问题。在数据写入量较大的场景中可以很好的实现数据均衡,搜索引擎默认按照主键进行HASH分区,同时也支持自定义的业务分区键。使用一级HASH分区时,如果自定义的HASH键存在热点问题,则可能导致大量数据写入同一个分区中,影响查询和写入性能,建议考虑多级分区,对数据进一步打散。
    • 创建搜索表,按照storeId列进行HASH分区(也就是一级HASH分区),分区数量为16。
      CREATE TABLE dt_partition (
        storeId integer, goodsId varchar, goodsPrice integer, constraint pk primary key(storeId))
        PARTITION BY HASH(storeId)
        PARTITIONS 16;
    • 创建搜索表,按照storeId列和goodsId列组合进行HASH分区(也就是二级HASH分区),加盐因子为2,分区数量为16,最多支持三级分区组合。
      CREATE TABLE dt_partition (
        storeId integer, goodsId varchar, goodsPrice integer, constraint pk primary key(storeId))
        PARTITION BY HASH(storeId(salt_factor=2),goodsId)
        PARTITIONS 16;
      重要
      • 加盐因子(salt_factor)是进一步散列相同storeId列值的数据,通常设置为一个较小的数值,并且数值与分区数量是两倍的数量关系。如果分区数量为16,当salt_factor大于4时,则无法散列数据。加盐因子的其他值表示如下:
        • salt_factor=1:表示相同storeId列的数据,不同goodsId列的数据会被散列到分区总数量的一半中。
        • salt_factor=2:表示相同storeId列的数据,不同goodsId列的数据会被散列到分区总数量的1/4中。
        • salt_factor=3:表示相同storeId列的数据,不同goodsId列的数据会被散列到分区总数量的1/8中。
      • 多级HASH分区(二级HASH分区或者三级HASH分区)除了可以散列数据,在查询数据场景中也大大提高了查询效率。例如在上述二级HASH分区中,查询数据时同时输入storeId列和goodsId列的过滤信息会确定在一个分区中进行数据检索,减少数据的扫描范围从而提高查询效率。
      • 使用二级HASH分区时,一级分区键(Lindorm搜索表的第一列即storeId列)必须设置加盐因子。使用三级HASH分区时,一级分区键和二级分区键都必须设置加盐因子。
      • 自定义分区键的值有以下限制:
        • 分区键值不可更改。
        • 分区键值不能为空。
    • 根据业务需求,如果需要将数据按照HASH分区和时间范围分区,可以将两个分区策略组合使用。
      CREATE TABLE dt_partition (
        storeId integer, goodsId varchar, goodsPrice integer, orderTime bigint, constraint pk primary key(storeId))
        PARTITION BY RANGE TIME(orderTime)
        PARTITION BY HASH(storeId) PARTITIONS 16
        WITH (RANGE_TIME_PARTITION_START='180', RANGE_TIME_PARTITION_INTERVAL='30', RANGE_TIME_PARTITION_TTL='180', RANGE_TIME_PARTITION_MAX_OVERLAP='10');