Choosing the right types, especially ids, times and collections, avoids subtle bugs and performance problems.
CQL has the usual scalars: text, int, bigint, smallint, double, decimal (exact, for money), boolean, blob, inet, date, time, timestamp (millisecond precision) and duration.
Identifiers deserve special attention:
uuidfor random ids (uuid()generates a version 4 UUID),timeuuidfor time-ordered unique ids (now()generates one;toTimestamp(id)extracts the time). Ideal as a clustering column for events, because two events in the same millisecond still get different ids.
Collections store small multi-valued data in one column: list<text>, set<text>, map<text, int>. You can update parts in place (tags = tags + {'sale'}). They're meant for small, bounded data, because a collection is read in full. Appending to lists is not idempotent and some list operations require a read before write internally; sets and maps are usually better.
User-defined types group fields: CREATE TYPE address (street text, city text). Mark collections of UDTs, or nested collections, as frozen<...>, which stores the value as one blob that can only be replaced as a whole.
counter columns support only increment and decrement and must live in tables containing only counters (plus the key). Cassandra 5.0 adds vector<float, n> for embeddings, searchable with SAI.
Example
CREATE TYPE IF NOT EXISTS shop.address (street text, city text, zip text);
CREATE TABLE shop.users (
user_id uuid PRIMARY KEY,
email text,
tags set<text>,
prefs map<text, text>,
home frozen<address>,
balance decimal,
created_at timestamp
);
INSERT INTO shop.users (user_id, email, tags, prefs, home, balance, created_at)
VALUES (uuid(), 'ana@example.com', {'beta'}, {'lang': 'hy'},
{street: 'Abovyan 1', city: 'Yerevan', zip: '0001'}, 12.50, toTimestamp(now()));
UPDATE shop.users SET tags = tags + {'vip'}, prefs['theme'] = 'dark'
WHERE user_id = 5b6962dd-3f90-4c93-8f61-eabfa4a803e2;Remember
- timeuuid gives unique, time-ordered ids; uuid gives random ones
- Collections are for small bounded data and are read whole
- frozen stores a UDT or collection as one replaceable value
- counter tables hold only counters; vector<float, n> is new in 5.0
Watch out for
- Using timestamp alone as a clustering column for events: two events in the same millisecond overwrite each other.