DDL

更新时间:
复制 MD 格式

Lindorm Cassandra Query Language (CQL) DDL statements let you create and manage keyspaces, tables, and indexes. This page covers the complete DDL syntax with examples.

Statements covered

Key concepts

Keyspaces and tables

Lindorm CQL stores data in tables grouped into keyspaces. A keyspace applies options — most commonly a replication strategy — to all tables it contains. In Lindorm CQL, the replication strategy and replica count use fixed defaults and cannot be modified.

Naming rules

Keyspace and table names follow the same rules:

name          ::=  unquoted_name | quoted_name
unquoted_name ::=  re('[a-zA-Z_0-9]{1, 48}')
quoted_name   ::=  '"' unquoted_name '"'
  • Names can contain letters, digits, and underscores.

  • Length: 1–48 characters.

  • Unquoted names are case-insensitive: myTable and mytable refer to the same table.

  • Quoted names are case-sensitive: "myTable" and "mytable" are different tables.

  • Qualify a table name with its keyspace to avoid ambiguity: ks.table and gs.table are distinct even if both contain a table named table.

Indexes

Lindorm CQL supports two index types:

  • Secondary indexes — query data by non-primary-key columns. The index name pattern is re('[a-zA-Z_0-9]+').

  • Search Index — powered by Lindorm's search engine. Supports multidimensional queries, ORDER BY sorting, and fuzzy match.

Before using Search Index, enable both the Search Index feature and Lindorm Tunnel Service (LTS). For details, see Overview.

CREATE KEYSPACE

Creates a keyspace.

Syntax

CREATE KEYSPACE [ IF NOT EXISTS ] keyspace_name WITH options
Note

Keyspaces in Lindorm CQL are equivalent to namespaces. The replication strategy and replica count cannot be configured — Lindorm always uses double-replica storage with durable_writes set to true.

Parameters

ParameterRequiredDefaultDescription
keyspace_nameYesName of the keyspace. Example: testks
replicationNo{'class': 'SimpleStrategy', 'replication_factor': 2}MAP type. Specifies replica count. Lindorm ignores the configured value and uses double-replica storage.
durable_writesNotrueBOOLEAN type. Specifies whether durable writes are enabled. Always true in Lindorm CQL.

Example

CREATE KEYSPACE testks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}

ALTER KEYSPACE

Modifies keyspace options.

Syntax

ALTER KEYSPACE keyspace_name WITH options
Note

The options parameter is the same as in CREATE KEYSPACE. Configuring replication or durable_writes has no effect — Lindorm CQL always uses the default values.

Example

ALTER KEYSPACE testks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}

USE

Sets the active keyspace for the session. Objects such as tables, user-defined types (UDTs), and user-defined functions (UDFs) are scoped to a keyspace.

Syntax

USE keyspace_name

Example

USE testks;

DROP KEYSPACE

Deletes a keyspace and all its contents.

Syntax

DROP KEYSPACE [ IF EXISTS ] keyspace_name
Warning

Dropping a keyspace immediately and permanently deletes all tables, UDTs, and UDFs it contains. This action cannot be undone.

Usage notes

  • Use IF EXISTS to suppress the error when the keyspace does not exist.

  • Only the root user can drop keyspaces.

Example

DROP KEYSPACE testks;

CREATE TABLE

Creates a table.

Syntax

CREATE TABLE [ IF NOT EXISTS ] table_name
    '('
        column_definition
        ( ',' column_definition )*
        [ ',' PRIMARY KEY '(' primary_key ')' ]
    ')' [ WITH table_options ]

column_definition  ::=  column_name cql_type [ STATIC ] [ PRIMARY KEY ]
primary_key        ::=  partition_key [ ',' clustering_columns ]
partition_key      ::=  column_name
                        | '(' column_name ( ',' column_name )* ')'
clustering_columns ::=  column_name ( ',' column_name )*
table_options      ::=  CLUSTERING ORDER BY '(' clustering_order ')' [ AND options ]
                        | options
clustering_order   ::=  column_name (ASC | DESC) ( ',' column_name (ASC | DESC) )*

Use IF NOT EXISTS to skip the statement silently when the table already exists.

Primary key

Every table requires a primary key that uniquely identifies each row. A primary key has two parts:

Partition key

The partition key is the first element of the primary key. It determines how data is distributed across nodes. A table must have at least one partition key column. To define a composite partition key, wrap multiple column names in parentheses.

Note

In Lindorm CQL, the partition key alone does not identify the physical node storing a row — it must be combined with clustering columns. This differs from standard Apache Cassandra CQL behavior.

Clustering columns

Clustering columns follow the partition key in the primary key definition. They are optional and determine the sort order of rows within a partition.

Primary key examples

DefinitionPartition keyClustering columns
PRIMARY KEY (a)anone
PRIMARY KEY (a, b, c)ab, c
PRIMARY KEY ((a, b), c)a, b (composite)c

Partition behavior example

CREATE TABLE personinfo (
    a int,
    b int,
    c int,
    d int,
    PRIMARY KEY ((a, b), c, d)
);

SELECT * FROM personinfo;
   a | b | c | d
  ---+---+---+---
   0 | 0 | 0 | 0    -- row 1: same partition as row 2 (a=0, b=0)
   0 | 0 | 1 | 1    -- row 2
   0 | 1 | 2 | 2    -- row 3: different partition (a=0, b=1)
   0 | 1 | 3 | 3    -- row 4
   1 | 1 | 4 | 4    -- row 5: different partition (a=1, b=1)

Rows 1 and 2 share the same partition (a=0, b=0) and reside on the same node. In standard Apache Cassandra CQL, the partition key alone determines placement — in Lindorm CQL, the full primary key (partition key + clustering columns) determines placement.

Table options

Supported options

OptionTypeDefaultDescription
default_time_to_liveint0Default TTL for all rows, in seconds. 0 means no expiration.
compressionmapSnappyCompressorCompression algorithm for SSTables. See Compression.
extensionsmapLindorm-specific properties: storage policy, cold/hot data separation, consistency level, and mutability. See Extensions.

Unsupported options

The following Cassandra table options are not supported by Lindorm CQL:

OptionCassandra default
comment(none)
speculative_retry99PERCENTILE
cdcfalse
gc_grace_seconds86400
bloom_filter_fp_chance0.00075
compactionSTCS
caching
memtable_flush_period_in_ms0
read_repairBLOCKING

Compression

Lindorm CQL supports three compression algorithms. Use the compression option to specify one when creating a table.

LZ4

CREATE TABLE personinfo (
   id int,
   name text,
   address text,
   PRIMARY KEY (id, name)
) WITH compression = {'class': 'LZ4Compressor'};

Zstd

CREATE TABLE personinfo (
   id int,
   name text,
   address text,
   PRIMARY KEY (id, name)
) WITH compression = {'class': 'ZstdCompressor'};

Snappy (default)

CREATE TABLE personinfo (
   id int,
   name text,
   address text,
   PRIMARY KEY (id, name)
) WITH compression = {'class': 'SnappyCompressor'};
Note

Change the compression algorithm at any time with ALTER TABLE.

Extensions

Use the extensions option to configure Lindorm-specific table properties.

STORAGE_POLICY — controls whether data is stored on cold or hot media.

ValueDescription
COLDStore data on cold (capacity) storage
DEFAULTStore data on hot storage (default)
-- Create a table with cold storage
CREATE TABLE personinfo (name text PRIMARY KEY, age int)
  WITH extensions = {'STORAGE_POLICY': 'COLD'};

-- Switch from cold to hot storage
ALTER TABLE personinfo WITH extensions = {'STORAGE_POLICY': 'DEFAULT'};

COLD_BOUNDARY — enables cold/hot data separation. Data written before the boundary (in seconds) is stored on cold media; newer data goes to hot media.

Important

Do not set STORAGE_POLICY to COLD on a table that uses COLD_BOUNDARY. If STORAGE_POLICY is COLD, disable cold/hot data separation first. For details, see Capacity storage.

-- Enable cold/hot data separation with an 86400-second (1 day) boundary
CREATE TABLE personinfo (name text PRIMARY KEY, age int)
  WITH extensions = {'COLD_BOUNDARY': '86400'};

-- Update the boundary to 1000 seconds
ALTER TABLE personinfo WITH extensions = {'COLD_BOUNDARY': '1000'};

-- Disable cold/hot data separation
ALTER TABLE personinfo WITH extensions = {'COLD_BOUNDARY': ''};

CONSISTENCY_TYPE — sets the consistency level for multi-zone deployments.

ValueDescription
eventualEventual consistency
timestampTimestamp-based consistency
basicBasic consistency
strongStrong consistency
-- Set strong consistency
CREATE TABLE personinfo (name text PRIMARY KEY, age int)
  WITH extensions = {'CONSISTENCY_TYPE': 'strong'};

-- Change to eventual consistency
ALTER TABLE personinfo WITH extensions = {'CONSISTENCY_TYPE': 'eventual'};

MUTABILITY — required before creating secondary or full-text indexes.

ValueRequires CONSISTENCY_TYPE=strong
IMMUTABLENo
MUTABLE_ALL (default)Yes
IMMUTABLE_ROWSYes
MUTABLE_LATESTYes
-- Set IMMUTABLE mutability
CREATE TABLE personinfo (name text PRIMARY KEY, age int)
  WITH extensions = {'MUTABILITY': 'IMMUTABLE'};

-- Change to MUTABLE_LATEST
ALTER TABLE personinfo WITH extensions = {'MUTABILITY': 'MUTABLE_LATEST'};

Limitations

  • The STATIC column modifier is not supported.

  • The partition key alone does not identify the physical storage node for a row.

Examples

-- Basic table with a single-column primary key
CREATE TABLE tb (name text PRIMARY KEY, age int);

-- Table with a 1000-second default TTL
CREATE TABLE ttltb (name text PRIMARY KEY, age int)
  WITH default_time_to_live = 1000;

-- Table with LZ4 compression
CREATE TABLE cptb (name text PRIMARY KEY, age int)
  WITH compression = {'sstable_compression': 'LZ4Compressor'};

-- Table with a 10-second cold/hot data separation boundary
CREATE TABLE hct (name text PRIMARY KEY, age int)
  WITH extensions = {'COLD_BOUNDARY': '10'};

ALTER TABLE

Modifies a table's columns or options.

Syntax

ALTER TABLE table_name alter_table_instruction

alter_table_instruction ::=  ADD column_name cql_type ( ',' column_name cql_type )*
                             | DROP column_name ( column_name )*
                             | WITH options

Usage notes

  • ADD — adds one or more columns. The primary key cannot be changed after table creation, so new columns cannot be part of the primary key.

  • DROP — not supported in Lindorm CQL. Column drop operations are ignored.

  • WITH — modifies table options. All options set at creation time can be changed except CLUSTERING ORDER. Modifiable options: default_time_to_live, compression, and extensions.

Example

CREATE TABLE personinfo (name text PRIMARY KEY, age int);
ALTER TABLE personinfo ADD address text;

DROP TABLE

Deletes a table and all its data.

Syntax

DROP TABLE [ IF EXISTS ] table_name
Warning

Dropping a table immediately and permanently deletes all data. This action cannot be undone.

Usage notes

  • Use IF EXISTS to suppress the error when the table does not exist.

  • Only the root user can drop tables.

Example

DROP TABLE personinfo;

TRUNCATE

Deletes all rows from a table while keeping the table schema.

Syntax

TRUNCATE [ TABLE ] table_name
Warning

TRUNCATE permanently deletes all data in the table. This action cannot be undone.

Usage notes

  • Only the root user can truncate tables.

Example

TRUNCATE TABLE personinfo;

CREATE INDEX

Creates a secondary index on a table column.

Syntax

CREATE [ CUSTOM ] INDEX [ IF NOT EXISTS ] [ index_name ]
    ON table_name '(' index_identifier ')'
    [ USING string [ WITH OPTIONS = map_literal ] ]

index_identifier ::=  column_name
                      | '(' column_name ')'

Existing data in the indexed column is indexed asynchronously after the index is created. New data is indexed automatically.

Use IF NOT EXISTS to suppress the error when the index already exists.

Single-column index

CREATE INDEX myindex ON personinfo (c2);
CREATE INDEX ON personinfo (c2);  -- index name is optional

Multi-column index

To index multiple columns, use CREATE CUSTOM INDEX with the Lindorm secondary index class:

CREATE CUSTOM INDEX myindex ON personinfo (c1, c2)
  USING 'com.alibaba.lindorm.cserver.schema.index.LindormSecondaryIndex';

DROP INDEX

Deletes a secondary index.

Syntax

DROP INDEX [ IF EXISTS ] index_name

Usage notes

  • index_name includes the keyspace qualifier.

  • Use IF EXISTS to suppress the error when the index does not exist.

Example

DROP INDEX myindex;

CREATE SEARCH INDEX

Creates a full-text index on one or more columns of a table.

Syntax

CREATE SEARCH INDEX [ IF NOT EXISTS ] index_name ON [keyspace_name.]table_name
    [ WITH COLUMNS (column1, ..., columnn) ]
  | [ WITH COLUMNS (*) ]

Usage notes

  • WITH COLUMNS (col1, col2, ...) — indexes the specified columns.

  • WITH COLUMNS (*) — indexes all columns.

  • In multi-zone deployments, set CONSISTENCY_TYPE and MUTABILITY on the table using the extensions option before creating a Search Index.

  • After creation, the index status is INACTIVE. Run REBUILD SEARCH INDEX to activate it.

Example

CREATE SEARCH INDEX schidx ON personinfo WITH COLUMNS (c2, c3);

DROP SEARCH INDEX

Deletes a full-text index.

Syntax

DROP SEARCH INDEX [IF EXISTS] ON [keyspace_name.]table_name;

Example

DROP SEARCH INDEX ON testks.personinfo;

REBUILD SEARCH INDEX

Activates a full-text index and builds the index for existing data.

Syntax

REBUILD SEARCH INDEX [ASYNC] [IF EXISTS] ON [keyspace_name.]table_name;

After CREATE SEARCH INDEX, the index status is INACTIVE. Run REBUILD SEARCH INDEX to set it to active and index any existing data.

Indexing existing data may take a significant amount of time. Use the ASYNC option to run the rebuild in the background.

Examples

-- Synchronous rebuild
REBUILD SEARCH INDEX ON personinfo;

-- Asynchronous rebuild
REBUILD SEARCH INDEX ASYNC ON personinfo;

ALTER SEARCH INDEX

Adds or removes indexed columns from a full-text index.

Syntax

ALTER SEARCH INDEX SCHEMA [IF EXISTS] ON [keyspace_name.]table_name
    ( ADD FIELD column_name
    | DROP FIELD column_name );
Important

After altering a Search Index, run REBUILD SEARCH INDEX to apply the changes and reset the index status.

The column specified in ADD FIELD or DROP FIELD must exist in the table.

Examples

-- Add a column to the index
ALTER SEARCH INDEX SCHEMA ON personinfo ADD (c3);

-- Remove a column from the index
ALTER SEARCH INDEX SCHEMA ON personinfo DROP (c2);