Use the CREATE TABLE statement to create a table in LindormTable or LindormTSDB. The statement supports data types such as VARCHAR, TIMESTAMP, and BIGINT, and table properties such as time-to-live (TTL) and compression algorithms.
Engines and versions
CREATE TABLE applies to LindormTable and LindormTSDB.
LindormTSDB supports the standard CREATE TABLE syntax in versions 3.4.32 and later. To view or upgrade your engine version, see LindormTSDB version guide and Minor version update.
Syntax
create_table_statement ::= CREATE TABLE [ IF NOT EXISTS ] table_identifier
'('
column_definition
( ',' column_definition )*
',' PRIMARY KEY '(' primary_key ')'
( ',' {KEY|INDEX} [index_identifier]
[ USING index_method_definition ]
[ INCLUDE column_identifier ( ',' column_identifier )* ]
[ WITH index_options ]
)*
')'
[ PARTITION BY partition_definition ]
[ ZORDER BY zorder_column_list ]
[ WITH table_options ]
column_definition ::= column_identifier data_type [ NOT NULL ]
primary_key ::= column_identifier [ ',' column_identifier (ASC|DESC)]
index_method_definition ::= { KV | SEARCH }
index_options ::= '('
option_definition (',' option_definition )*
')'
partition_definition ::= HASH '(' column_identifier (',' column_identifier )* ')'
zorder_column_list ::= column_identifier ( ',' column_identifier )*
table_options ::= '(' option_definition (',' option_definition )* ')'
option_definition ::= option_identifer '=' string_literalEngine comparison
The CREATE TABLE syntax differs between LindormTable and LindormTSDB.
| Syntax element | LindormTable | LindormTSDB |
|---|---|---|
| Table name (table_identifier) | Supported | Supported |
| Column definition (column_definition) | Supported | Supported |
| Primary key (primary_key) | Supported | Supported |
| Index expression (KEY|INDEX) | Supported | Not supported |
| Partition (partition_definition) | Not supported | Supported |
| Table properties (table_options) | Supported | Not supported |
Usage notes
Table name
Allowed characters: digits, uppercase letters, lowercase letters, periods (
.), hyphens (-), and underscores (_).Cannot start with a period (
.) or a hyphen (-).Length: 1 to 255 characters.
Column definition
| Element | Required | Notes |
|---|---|---|
| Column name | Yes | Allowed characters: digits, uppercase/lowercase letters, periods (.), hyphens (-), and underscores (_). Cannot use reserved keywords. Maximum length: 255 bytes. |
| Data type | Yes | For supported data types, see Data types. |
| NULL constraint | No | See the note below. |
TIMESTAMP type (LindormTSDB only):
Only one column per table can be of the TIMESTAMP type.
LindormTSDB encodes and parses timestamps based on UTC+8.
Legacy 32-bit Unix timestamps must be multiplied by 1000 before writing to LindormTSDB. Writing a 32-bit Unix timestamp directly causes a semantic interpretation error. For example,
1641009600represents2022-01-01 12:00:00in legacy systems, but is interpreted as1970-01-20 07:50:09 (UTC+8)in LindormTSDB.
NULL constraint behavior:
Currently, Lindorm SQL does not validate NULL constraints at the SQL layer — the storage engine performs this validation, and rules vary by engine. To ensure correct data writes:
Specify
NOT NULLfor all primary key columns.Do not specify
NOT NULLfor non-primary key columns.
Primary key
A primary key uniquely identifies rows in a table. It consists of one or more columns and must be specified when creating a table.
Primary keys cannot be modified after creation. Design your primary key carefully before creating the table.
LindormTable primary key limits:
| Item | Limit |
|---|---|
| Maximum length of a single primary key column | 2 KB |
| Maximum total length of all primary key columns | 30 KB |
| Maximum length of a single non-primary key column | 2 MB |
LindormTSDB primary key structure:
In a time series table, primary key columns serve two distinct roles:
Tag column: A primary key column of the VARCHAR type. Identifies the data source — for example, device ID in Internet of Things (IoT) scenarios, vehicle identifier in Internet of Vehicles (IoV) scenarios, or application ID or
ip:portin monitoring scenarios.Timestamp column: A primary key column of the TIMESTAMP type. Only one timestamp column is allowed per table.
The primary key can contain one or more VARCHAR (tag) columns, but only one TIMESTAMP column. All primary key columns must be VARCHAR or TIMESTAMP type.
For guidance on designing primary keys for time series tables, see Best practices for PRIMARY KEY design.
Index expression (KEY|INDEX)
Use the KEY or INDEX keyword in a CREATE TABLE statement to create an index at table creation time. You can create secondary indexes and search indexes this way.
The index expression is supported only in LindormTable 2.7.7 or later and Lindorm SQL 2.8.6.0 or later. To check your versions, see LindormTable version guide and SQL version guide. If you cannot upgrade in the console, contact Lindorm technical support on DingTalk at s0s3eg3.
Index naming: If no index name is specified, the system generates one in the format table_name_idx_${auto_increment_id}.
Secondary index redundancy (when INCLUDE is not specified):
| Lindorm SQL version | Default redundancy behavior |
|---|---|
| 2.9.3.10 and later | Columns are not redundantly stored by default |
| Earlier than 2.9.3.10 | All columns are redundantly stored by default (equivalent to INDEX_COVERED_TYPE=COVERED_ALL_COLUMNS_IN_SCHEMA; for dynamic tables, equivalent to COVERED_DYNAMIC_COLUMNS) |
Default table properties when using KEY/INDEX (if MUTABILITY and CONSISTENCY are not specified):
CONSISTENCY = 'strong'MUTABILITY = 'MUTABLE_LATEST'
Residual state on index creation failure: If an exception occurs during index creation, the table and index may remain in a residual state and are not automatically cleared. They remain visible via SHOW and DESCRIBE statements, but data writes and queries may fail. Manually drop the residual table and index, then recreate them.
Partition
Partitions are supported only in LindormTSDB. The columns used in PARTITION BY must be VARCHAR columns in the primary key.
Syntax: PARTITION BY HASH(column1, column2, ..., columnN)
Table properties
Only LindormTable supports table properties via the WITH keyword.
| Option | Type | Default | Description |
|---|---|---|---|
| COMPRESSION | STRING | None (ZSTD from LindormTable 2.3.4 onward) | Compression algorithm. Valid values: SNAPPY, ZSTD, LZ4. |
| TTL | INT | Empty (no expiry) | Time-to-live for data, in seconds. To remove TTL, set it to an empty string. See ALTER TABLE examples. |
| COMPACTION_MAJOR_PERIOD | LONG | Math.Min(TTL, 1728000000) ms; if no TTL: 20 days (1,728,000,000 ms) | Period for major compaction, in milliseconds. |
| MUTABILITY | STRING | MUTABLE_LATEST | Mutability of the base table, related to index behavior. Valid values: IMMUTABLE, IMMUTABLE_ROWS, MUTABLE_LATEST, MUTABLE_ALL, MUTABLE_UDT. Cannot be modified after index creation — drop all indexes before changing. See High-performance native secondary indexes. |
| CONSISTENCY | STRING | eventual | Consistency level. Valid values: eventual, strong. For multi-zone instances with read-after-write operations (such as increments, appends, or index updates), set to strong. |
| NUMREGIONS | INT | — | Number of regions to pre-create for the table. |
| CHS | INT | — | Hot/cold data boundary, in seconds. Requires cold storage to be enabled. Must be used with CHS_L2='storagetype=COLD'. See Hot and cold data separation. |
| STARTKEY and ENDKEY | Same type as the first primary key column | — | Start and end keys for pre-created region partitions. Requires NUMREGIONS. Supported types: SMALLINT, INTEGER, BIGINT, CHAR, VARCHAR, FLOAT, DOUBLE. |
| SPLITKEYS | Same type as the first primary key column | — | Start keys for all pre-created partitions, comma-separated. Supported since LindormTable 2.5.4. Cannot be used with NUMREGIONS, STARTKEY, or ENDKEY. Commas inside double quotes are treated as regular characters. Supported types: same as STARTKEY/ENDKEY. |
| SPLITALGO | STRING | — | Splitting algorithm for pre-created partitions. Valid values: HexStringSplit (splits by hexadecimal bytes), UniformSplit (even split by original byte values). |
| DYNAMIC_COLUMNS | STRING | False | Enables dynamic columns. Valid values: True, False. Dynamic columns support only the Varbinary type. See Dynamic columns. |
| VERSIONS | STRING | 1 | Number of versions to retain per column value. Must be an integer >= 1. Large values affect query and storage performance — keep this at 1 unless multi-version retention is required. See Multi-version data management. |
| BLOB_BUCKET_NAME | STRING | — | Creates a BUCKET for a table with BLOB columns. Supported since LindormTable 2.6.4. BUCKET name rules: lowercase letters, digits, periods (.), and hyphens (-); 3–63 characters; cannot start or end with a hyphen; no consecutive periods. |
In LindormTable versions earlier than 2.2.16, theWITHkeyword is not supported. Enclose property keywords in single quotes instead. For string values, also enclose the value in single quotes. Example:CREATE TABLE IF NOT EXISTS t1(c1 varchar, c2 bigint, c3 int, c4 int, PRIMARY KEY(c1,c2)) 'CONSISTENCY'='strong';
Examples
Create a basic table
CREATE TABLE sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time)
);Run DESCRIBE table sensor; to verify the table was created.
Create a table with a secondary index
CREATE TABLE IF NOT EXISTS sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time),
KEY (temperature, time)
);To verify:
Run
DESCRIBE table sensor;to check the table.Run
SHOW INDEX FROM sensor;to check the secondary index.
Set TTL and compression algorithm
Set TTL to 30 days (2,592,000 seconds) and compression to ZSTD.
CREATE TABLE sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time)
) WITH (COMPRESSION='ZSTD', TTL='2592000');To verify:
Run
DESCRIBE table sensor;to check the table.In the cluster management system, navigate to the Overview page, click the table name, and click View Table Properties in the Current Details Table area to confirm the
COMPRESSIONandTTLvalues.
Set the major compaction period
Set the major compaction period to 10 days (864,000,000 milliseconds).
CREATE TABLE sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time)
) WITH (COMPACTION_MAJOR_PERIOD='864000000');To verify: Run DESCRIBE table sensor;, or click View Table Properties in the Current Details Table area of the cluster management system.
Enable dynamic columns
CREATE TABLE sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time)
) WITH (DYNAMIC_COLUMNS='TRUE');To verify: Run DESCRIBE table sensor;, or click View Table Properties in the Current Details Table area of the cluster management system.
Set hot/cold data boundary
Archive data older than 86,400 seconds (1 day) to cold storage.
CREATE TABLE sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time)
) WITH (CHS = '86400', CHS_L2 = 'storagetype=COLD');CHSrequires cold storage to be enabled and must be used together withCHS_L2='storagetype=COLD'.
To verify: Run DESCRIBE table sensor;, or click View Table Properties in the Current Details Table area of the cluster management system to confirm the CHS and CHS_L2 values.
Combine multiple properties
Set compression, TTL, and hot/cold data boundary together.
CREATE TABLE sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time)
) WITH (
COMPRESSION='ZSTD',
CHS = '86400',
CHS_L2 = 'storagetype=COLD',
TTL = '2592000');To verify: Run DESCRIBE table sensor;, or click View Table Properties in the Current Details Table area of the cluster management system to confirm the COMPRESSION, CHS, CHS_L2, and TTL values.
Pre-create partitions with start and end keys
Pre-create five partitions with start key 1000 and end key 9000. STARTKEY and ENDKEY require NUMREGIONS.
CREATE TABLE sensor (
p1 INTEGER NOT NULL,
c1 INTEGER,
c2 VARCHAR,
c3 VARCHAR,
PRIMARY KEY(p1)
) WITH (NUMREGIONS='5', STARTKEY='1000', ENDKEY='9000');To verify: Run DESCRIBE table sensor;, or navigate to the Shard Details area in the cluster management system to view the startKey and endKey values for each shard.
Pre-create partitions with explicit split keys
Specify five split keys to pre-create six partitions. SPLITKEYS cannot be used with NUMREGIONS, STARTKEY, or ENDKEY.
CREATE TABLE sensor (
p1 INT NOT NULL,
p2 INT NOT NULL,
c1 VARCHAR,
c2 BIGINT,
PRIMARY KEY(p1, p2)
) WITH (SPLITKEYS = '100000,300000,500000,700000,900000');To verify: Run DESCRIBE table sensor;, or view the startKey and endKey values in the Shard Details area of the cluster management system.
Specify a partition key column
For queries that target a single device's instantaneous data, specify device_id as the partition key to control data distribution.
CREATE TABLE sensor (
device_id VARCHAR NOT NULL,
region VARCHAR NOT NULL,
time TIMESTAMP NOT NULL,
temperature DOUBLE,
humidity BIGINT,
PRIMARY KEY(device_id, region, time)
) PARTITION BY HASH(device_id);Run DESCRIBE TABLE sensor; to verify the table creation result.
Create a spatio-temporal data table
Any spatial type (GEOMETRY) — accepts any spatial data type:
CREATE TABLE geoms(gid INT, g GEOMETRY, PRIMARY KEY(gid));Write data of any spatial type:
UPSERT INTO geoms(gid, g) VALUES
(0, ST_GeomFromText('POINT(-10.1 3.3)')),
(1, ST_GeomFromText('LINESTRING(-12.2 4.3, -10.2 4.3)')),
(2, ST_GeomFromText('POLYGON((2 2, 2 8, 8 8, 8 2, 2 2))'));Point type only:
CREATE TABLE pts(gid INT, g GEOMETRY(POINT), PRIMARY KEY(gid));UPSERT INTO pts(gid, g) VALUES(0, ST_MakePoint(0,0)),(1, ST_MakePoint(1,1));Polygon type only:
CREATE TABLE polys(gid INT, g GEOMETRY(POLYGON), PRIMARY KEY(gid));UPSERT INTO polys(gid,g) VALUES(0, ST_GeomFromText('POLYGON((2 2, 2 8, 8 8, 8 2, 2 2))'));LineString type only:
CREATE TABLE lines(gid INT, g GEOMETRY(LINESTRING), PRIMARY KEY(gid));UPSERT INTO lines(gid,g) VALUES(0, ST_GeomFromText('LINESTRING(-12.2 4.3, -10.2 4.3)'));MULTIPOINT type only:
CREATE TABLE multipoints(gid INT, g GEOMETRY(MULTIPOINT), PRIMARY KEY(gid));UPSERT INTO multipoints(gid,g) VALUES(0, ST_GeomFromText('MULTIPOINT (10 40, 40 30, 20 20, 30 10)'));MULTILINESTRING type only:
CREATE TABLE multilines(gid INT, g GEOMETRY(MULTILINESTRING), PRIMARY KEY(gid));UPSERT INTO multilines(gid,g) VALUES(0, ST_GeomFromText('MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))'));MULTIPOLYGON type only:
CREATE TABLE multipolys(gid INT, g GEOMETRY(MULTIPOLYGON), PRIMARY KEY(gid));UPSERT INTO multipolys(gid,g) VALUES(0, ST_GeomFromText('MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))'));GEOMETRYCOLLECTION type only:
CREATE TABLE collections(gid INT, g GEOMETRY(GEOMETRYCOLLECTION), PRIMARY KEY(gid));UPSERT INTO collections(gid,g) VALUES(0, ST_GeomFromText('GEOMETRYCOLLECTION (POINT (40 10), LINESTRING (10 10, 20 20, 10 40), POLYGON ((40 40, 20 45, 45 30, 40 40)))'));Multiple spatial columns:
CREATE TABLE mix(gid INT, pt GEOMETRY(POINT), ply GEOMETRY(POLYGON), PRIMARY KEY(gid));