Skip to content
Navigation

Type at least two characters. Search covers page titles, headings, tags and database names.

↑ ↓ to navigateEnter to openEsc to close0 pages
ScyllaDBintermediate

ScyllaDB Data Modeling

The Cassandra modelling rules, plus the shard-level considerations specific to ScyllaDB.

2 min readIntermediateUpdated Edit this page

ScyllaDB uses the Cassandra data model, so Cassandra Data Modeling applies in full: design one table per query, put every equality filter in the partition key, use clustering columns for ordering, and keep partitions bounded.

Three considerations are specific to ScyllaDB.

A partition maps to one core

In Cassandra a hot partition saturates the nodes that own it. In ScyllaDB it saturates a single shard — one core on one node — while the other cores on the same machine stay idle.

The practical effect is that partition key cardinality matters more, not less, on a smaller cluster of larger machines. A key that produces a few thousand partitions may distribute acceptably across six Cassandra nodes and badly across three ScyllaDB nodes with 32 shards each.

Bucketing granularity

The same time-bucket pattern applies, and the reasoning about size is unchanged — partitions should stay well bounded so that reads, compaction and repair remain cheap.

CREATE TABLE readings (
    device_id uuid,
    bucket    date,
    ts        timestamp,
    value     double,
    PRIMARY KEY ((device_id, bucket), ts)
) WITH CLUSTERING ORDER BY (ts DESC)
  AND compaction = {
      'class': 'TimeWindowCompactionStrategy',
      'compaction_window_unit': 'DAYS',
      'compaction_window_size': 1
  }
  AND default_time_to_live = 2592000;

Shard-aware clients

A shard-aware driver routes each request directly to the core owning the partition. To benefit, the application must pass the partition key in a form the driver can hash — which means using prepared statements with bound parameters rather than string-concatenated CQL.

# Prepared: the driver knows the key and routes to the right shard.
stmt = session.prepare("SELECT * FROM readings WHERE device_id = ? AND bucket = ?")
session.execute(stmt, (device_id, bucket))

Unprepared statements cannot be routed and take an extra internal hop.

Materialized views and secondary indexes

ScyllaDB implements both, and both carry the same caution as in Cassandra: a global secondary index queries across the cluster, and a materialized view adds write amplification and its own consistency considerations. Prefer an explicitly maintained second table for high-traffic access paths, and verify the behaviour of views on the exact ScyllaDB version before depending on them.