Skip to main content
DB

Concepts

Tables

The three table modes, APPEND, UPSERT and VERSIONED, and how keys, shards, partitions, order and storage profile shape a table.

A table is a typed schema plus a mode. The mode decides which writes the table accepts and which state it keeps. Every other clause of CREATE TABLE shapes where rows live and how they are stored; none of them changes the mode.

The three modes

ModeKeyAccepted writesState kept
APPENDnone: the engine assigns each row its identityINSERT onlyevery row
UPSERT (the default)exactly one PRIMARY KEYINSERT, UPSERT, REPLACE, UPDATE, DELETEthe latest row per key
VERSIONEDexactly one PRIMARY KEYthe same as UPSERTthe current row per key and every accepted version

MODE is optional; a table without it is an UPSERT table. A keyed mode has one PRIMARY KEY, and an APPEND table carries no primary key.

APPEND: a log of events

An append table keeps every row it accepts. Use it for events, readings and other facts that are never corrected in place.

CREATE TABLE transfers (
  chain_id UINT16 NOT NULL,
  token STRING NOT NULL,
  sender STRING NOT NULL,
  recipient STRING NOT NULL,
  amount UINT256 NOT NULL,
  transferred_at DATETIME64(3, 'UTC') NOT NULL,
  _index UINT128 NOT NULL,
  INDEX transfers_ts (transferred_at) USING MINMAX SCOPE HISTORY GRANULE 8192
)
MODE APPEND
SHARD BY (token) SHARDS AUTO
PARTITION BY MONTH(transferred_at)
ORDER BY (chain_id, token, _index)
STORAGE PROFILE COLUMNAR;

An append table takes inserts; corrections are derived downstream, in a keyed table maintained by a transformation.

UPSERT: the latest row per key

An upsert table holds one current row per primary key. A later write to the same key changes that row; the previous value is not retained.

CREATE TABLE token_metadata (
  chain_id UINT16 NOT NULL,
  token STRING NOT NULL,
  symbol STRING NULL ENCODING LOW_CARDINALITY,
  decimals UINT8 NULL,
  PRIMARY KEY (chain_id, token)
)
MODE UPSERT
SHARD BY (token) SHARDS 4;

VERSIONED: current state plus history

A versioned table also keeps one current row per key, and it retains every accepted version beside it. VALID BY and REVISION BY decide which version is current when writes arrive out of order. See Versioned tables.

CREATE TABLE balances (
  chain_id UINT16 NOT NULL,
  address STRING NOT NULL,
  token STRING NOT NULL,
  amount UINT256 NULL,
  updated_at DATETIME64(3, 'UTC') NULL,
  balance_index UINT128 NULL,
  balance_version UINT64 NULL,
  transfer_count UINT64 NULL,
  last_transfer_at DATETIME64(3, 'UTC') NULL,
  activity_index UINT128 NULL,
  PRIMARY KEY (chain_id, address, token),
  ATTRIBUTE GROUP holding (amount, updated_at, balance_index, balance_version)
    VALID BY (balance_index)
    REVISION BY (balance_version),
  ATTRIBUTE GROUP activity (transfer_count, last_transfer_at, activity_index)
    VALID BY (activity_index)
)
MODE VERSIONED
SHARD BY (address) SHARDS AUTO
ORDER BY (chain_id, address, token);

Columns and nulls

A column is NOT NULL unless NULL is written after its type. A DEFAULT takes one literal. A write that omits a column uses its default, or NULL when the column is nullable. Primary-key columns and the columns named by VALID BY and REVISION BY are non-null. The types are listed in Data types.

Write kinds

StatementMeaning
INSERTcreates a row; on a keyed table it reports an existing key
UPSERTchanges the named columns of an existing row, or creates the row
REPLACEwrites a complete row for the key
UPDATEchanges the named columns of existing rows
DELETEremoves rows by key or by condition

Statement grammar is on INSERT and UPDATE and DELETE.

A keyed table can split its columns into attribute groups: each group is written and ordered on its own, so several writers can each own part of a row.

Keys, shards, partitions and order

Four clauses are independent of each other:

ClauseDecidesDefault
PRIMARY KEY (…)row identity on a keyed tablenone (required on UPSERT and VERSIONED)
SHARD BY (…) SHARDS nwhich shard owns a row, and how many shards the table starts withthe primary key, and the node's automatic shard count
PARTITION BY …how rows of a shard are bucketed for pruning: NONE, a UTC time bucket HOUR(col), DAY(col) or MONTH(col), or HASH(col, buckets)NONE
ORDER BY (…)the physical order of rows inside stored partsthe primary key

Each shard is a tablet. Tablets are replicated across nodes and split and merge as the table grows. See ALTER TABLE for schema changes.

Storage profile

STORAGE PROFILE ROW | COLUMNAR | HYBRID | DEFAULT selects the physical layout. ROW stores keyed rows for point access; COLUMNAR and HYBRID write column blocks that favour scans. Append tables always store their parts as column blocks. Per-column ENCODING, COMPRESSION and CODEC choose the encoding of each column inside those blocks. See CREATE TABLE and Storage.

Inspecting a table

SHOW CREATE TABLE returns the stored definition as a statement that can be run again:

SHOW CREATE TABLE balances;

The other inspection statements are on Introspection.

On this page