Chapter 08 · CQL Data Types, Collections, Tuples, UDTs, Static Columns, and Frozen Values

Scalar Types, Timestamps / Dates, UUID / timeuuid, Decimal / Varint, Blob, Duration, and Conversion

Choose Cassandra scalar types from exact range, encoding, ordering, time, precision, and driver-decoding semantics rather than familiar SQL names.

Intermediate90–120 minutesScalar-type + decoding labApache Cassandra 5.0.9 · cqlsh/nodetool · Java Driver 4.19.3 optional · UCSLast reviewed: September 2026

Learning outcomes

AtlasMart is ingesting order totals, event clocks, identifiers, checksums, service windows, and high-precision counters from multiple services. Choosing text for everything would move validation bugs into application code and make ordering, arithmetic, range checks, and driver decoding ambiguous. Cassandra Query Language (CQL) scalar types are part of the storage contract: they define accepted values, binary representation, comparison behavior, and the native-protocol type a driver decodes.

01

Choose scalar types from value domain, precision, ordering, range, and interoperability requirements.

02

Distinguish timestamp/date/time from timeuuid and explain what each can and cannot encode.

03

Use decimal for arbitrary-precision decimal arithmetic and varint for arbitrary-precision integers without assuming fixed-width storage.

04

Represent opaque bytes with blob and calendar/clock components with duration without pretending either is ordinary text.

05

Inspect server values in cqlsh and map representative columns to Apache Java Driver 4.19.3 decoding APIs.

Chapter 08 lab baseline

The mandatory labs use the pinned cassandra:5.0.9 image. Java 17, cqlsh, and nodetool are the versions bundled by that image. The course topology is three disposable nodes (atlasmart-cass-1..3) in cluster atlasmart-course, datacenter dc1, racks rack1..rack3, 16 vnodes per node, replication factor (RF) 3, and LOCAL_QUORUM for consistency-sensitive examples. Authentication, client TLS, internode TLS, and remote JMX are not enabled in this isolated learning network; production must secure those boundaries separately. Chapter 08 uses keyspace atlasmart_types; new tables explicitly use UnifiedCompactionStrategy (UCS), default table TTL is zero unless stated, and gc_grace_seconds is not changed. Storage-Attached Indexing (SAI) and vector search are not required. Apache Cassandra Java Driver 4.19.3 is used only in optional decoding snippets; the mandatory path remains free/local with cqlsh.

Execution disclosure and resource path

The commands and CQL below are documentation- and syntax-reviewed but were not executed in this generation environment. Treat output as an expected shape, then capture exact UUIDs, time values, SSTable paths, tombstone counters, and driver-decoded values on your machine. If three nodes are too heavy, use one disposable node and RF=1 to learn type/mutation semantics, but do not treat that reduced topology as evidence about RF=3 availability or repair behavior.

1. A type is a storage and comparison contract

Cassandra types are not cosmetic aliases. int and bigint are fixed-width signed integers with different ranges; varint is arbitrary precision. decimal stores arbitrary-precision decimal values and is a better semantic fit for exact monetary quantities than binary floating point. uuid is an opaque universally unique identifier. timeuuid is specifically a version-1 UUID whose timestamp component can support time ordering and conversion functions. blob stores uninterpreted bytes, expressed in CQL with a 0x-prefixed hexadecimal literal. duration stores months, days, and nanoseconds as separate components; because calendar months do not have one fixed number of seconds, do not reduce duration to a single millisecond count without a reference date.

AtlasMart value Candidate CQL type Reason Boundary to test
order total decimal exact decimal quantity scale/rounding belongs to business logic
inventory sequence varint can exceed fixed integer width driver big-integer decoding
event instant timestamp absolute millisecond instant timezone formatting is client-side presentation
business date date calendar date without time-of-day do not smuggle timezone into it
ordered event id timeuuid UUID identity + embedded v1 time not every UUID is a timeuuid
checksum bytes blob opaque binary application owns interpretation
fulfilment SLA duration months/days/nanos components calendar arithmetic is context-dependent

2. Lab: store and inspect representative scalar values

bash · verify or recreate the disposable course cluster
# Verify the shared course lab if it already exists.docker exec atlasmart-cass-1 nodetool versiondocker exec atlasmart-cass-1 nodetool status# Standalone local recreation path. Skip resources that already exist.docker network inspect atlasmart-cassandra >/dev/null 2>&1 || docker network create atlasmart-cassandradocker volume create atlasmart-cass-1-datadocker volume create atlasmart-cass-2-datadocker volume create atlasmart-cass-3-datadocker inspect atlasmart-cass-1 >/dev/null 2>&1 || docker run -d --name atlasmart-cass-1 --hostname atlasmart-cass-1 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack1 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -v atlasmart-cass-1-data:/var/lib/cassandra cassandra:5.0.9# Wait for node 1 to answer before starting peers.docker exec atlasmart-cass-1 nodetool statusdocker inspect atlasmart-cass-2 >/dev/null 2>&1 || docker run -d --name atlasmart-cass-2 --hostname atlasmart-cass-2 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack2 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -e CASSANDRA_SEEDS=atlasmart-cass-1 -v atlasmart-cass-2-data:/var/lib/cassandra cassandra:5.0.9docker inspect atlasmart-cass-3 >/dev/null 2>&1 || docker run -d --name atlasmart-cass-3 --hostname atlasmart-cass-3 --network atlasmart-cassandra -e CASSANDRA_CLUSTER_NAME=atlasmart-course -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack3 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_NUM_TOKENS=16 -e CASSANDRA_SEEDS=atlasmart-cass-1 -v atlasmart-cass-3-data:/var/lib/cassandra cassandra:5.0.9# Continue only after all nodes show UN.docker exec atlasmart-cass-1 nodetool statusdocker exec atlasmart-cass-1 cqlsh -e "CREATE KEYSPACE IF NOT EXISTS atlasmart_types WITH replication = {'class':'NetworkTopologyStrategy','dc1':3};"docker exec atlasmart-cass-1 cqlsh -e "DESCRIBE KEYSPACE atlasmart_types"
sql · create the scalar probe
CREATE TABLE atlasmart_types.scalar_probe (    tenant_id uuid,    event_id timeuuid,    recorded_at timestamp,    business_date date,    opening_time time,    order_total decimal,    huge_sequence varint,    checksum blob,    fulfilment_sla duration,    note text,    PRIMARY KEY ((tenant_id), event_id)) WITH CLUSTERING ORDER BY (event_id DESC)  AND compaction = {'class':'UnifiedCompactionStrategy'};DESCRIBE TABLE atlasmart_types.scalar_probe;
sql · insert values and use current 5.0 time conversions
CONSISTENCY LOCAL_QUORUM;INSERT INTO atlasmart_types.scalar_probe(tenant_id,event_id,recorded_at,business_date,opening_time,order_total,huge_sequence,checksum,fulfilment_sla,note)VALUES(11111111-1111-1111-1111-111111111111, now(), '2026-09-07T12:00:00Z', '2026-09-07', '12:34:56.123456789', 1299.95, 123456789012345678901234567890, 0x41424344, 2d3h, 'paid');SELECT tenant_id,event_id,to_timestamp(event_id),to_unix_timestamp(event_id),recorded_at,business_date,opening_time,order_total,huge_sequence,checksum,fulfilment_slaFROM atlasmart_types.scalar_probeWHERE tenant_id=11111111-1111-1111-1111-111111111111;

The exact generated event_id differs every run. What matters is that to_timestamp(event_id) and to_unix_timestamp(event_id) decode the embedded version-1 UUID time, while the separately stored recorded_at remains an ordinary timestamp. Cassandra 5.0 uses the snake_case conversion names; older camelCase spellings are deprecated.

3. Driver decoding is part of the contract

An application driver does not receive a bag of strings. Native-protocol metadata identifies each CQL type, and the codec layer maps it to language types. The optional Java example below uses Apache Cassandra Java Driver 4.19.3; exact imports/configuration should be rechecked if you use another driver or release.

java · optional Java Driver 4.19.3 decoding boundary
Row row = session.execute(    "SELECT event_id, recorded_at, order_total, huge_sequence, checksum, fulfilment_sla " +    "FROM atlasmart_types.scalar_probe WHERE tenant_id=?",    UUID.fromString("11111111-1111-1111-1111-111111111111")).one();UUID eventId = row.getUuid("event_id");Instant recordedAt = row.getInstant("recorded_at");BigDecimal total = row.getBigDecimal("order_total");BigInteger sequence = row.getBigInteger("huge_sequence");ByteBuffer checksum = row.getByteBuffer("checksum");CqlDuration sla = row.getCqlDuration("fulfilment_sla");
Wrong approach: cast everything to text.

That hides precision/range violations until later, loses binary type metadata, makes ordering semantics application-dependent, and encourages accidental timezone or money bugs. Repair the design by choosing the narrowest semantic type that preserves the business invariant, then test both CQL literals and driver codecs.

4. Production judgment

Scalar choice affects partition-key serialization, clustering comparison, payload size, CPU for numeric conversion, application serialization, and migration compatibility. Do not change a column's type casually: modern CQL removed arbitrary ALTER TYPE changes for table columns, so incompatible type redesign normally means a new column/table and controlled migration. For identifiers, use uuid unless time ordering is part of the contract; for event ordering, timeuuid can help but does not replace a separately modeled business timestamp. For money, avoid binary floating point when exact decimal semantics are required. For blob, validate size/content at the application boundary because Cassandra cannot interpret your encoding. Duration arithmetic and cross-language decoding deserve explicit tests.

Verification checklist

  • The scalar table schema matches the intended value domains rather than generic text columns.
  • timeuuid conversion produces a timestamp/epoch value derived from the generated identifier.
  • Decimal/varint values round-trip without fixed-width truncation.
  • Blob output is still opaque bytes; interpretation remains outside Cassandra.
  • Optional driver decoding uses typed getters rather than string parsing.

Check your understanding

  1. Why is timeuuid not interchangeable with any UUID?
  2. Why prefer decimal over double for exact money?
  3. What does a blob tell Cassandra about its contents?
  4. Why is duration not simply a millisecond count?
  5. What should a driver test verify?
Review the answers

1. A timeuuid is specifically a version-1 UUID with time semantics; an arbitrary UUID may not contain that ordered timestamp structure.

2. Decimal preserves base-10 arbitrary-precision semantics; binary floating point can introduce representation error.

3. Nothing beyond bytes. The application owns the encoding and validation.

4. It carries months, days, and nanoseconds separately; month length depends on calendar context.

5. That server types decode into the intended language types and preserve precision/range semantics.

bash · reset Chapter 08 data when desired
# Destructive only to this disposable chapter keyspace.docker exec atlasmart-cass-1 cqlsh -e "DROP KEYSPACE IF EXISTS atlasmart_types;"# Keep shared course containers for Chapter 09, or remove them for a full reset:# docker rm -f atlasmart-cass-1 atlasmart-cass-2 atlasmart-cass-3# docker volume rm atlasmart-cass-1-data atlasmart-cass-2-data atlasmart-cass-3-data# docker network rm atlasmart-cassandra

Summary and next bridge

Scalar types are executable domain constraints, not decoration. Next we move from one typed value per cell to lists, sets, and maps—where growth, element mutation, TTL, and tombstone behavior become part of the storage cost.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.