CQL Fundamentals

CQL Data Types

Master Cassandra's rich type system! From simple text and numbers to complex collections and UUIDs.

๐Ÿ“– The Story: Sarah's E-Commerce Disaster

Sarah just launched her first e-commerce app. She stored EVERYTHING as TEXT because "it's simple!" But then Black Friday happened...

โŒ The WRONG Way (Everything as TEXT)

CREATE TABLE products_wrong ( product_id TEXT, price TEXT, -- "19.99" stored as text! stock TEXT, -- "150" stored as text! created TEXT -- "2024-01-15" as text! );

What Went Wrong:

  • ๐Ÿ’ธ Price sorting broke: "9.99" came BEFORE "19.99" alphabetically!
  • ๐Ÿ“Š Can't calculate totals: Can't SUM text
  • ๐Ÿ—“๏ธ Date filtering disaster: String comparison chaos

Result: $50,000 in lost Black Friday sales! ๐Ÿ˜ฑ

โœ… The RIGHT Way (Proper Types)

CREATE TABLE products_correct ( product_id UUID PRIMARY KEY, name TEXT, price DECIMAL, stock INT, created TIMESTAMP );

Next Black Friday: Zero crashes! Revenue up 40%! ๐Ÿš€

๐Ÿ”ค Simple Data Types

๐Ÿ“

TEXT / VARCHAR

TEXT / VARCHAR

Purpose: Store letters, words, sentences - any UTF-8 text!

Max Size: Up to 2GB (but keep it reasonable - a few KB typical)

๐Ÿ“ฆ How Cassandra Stores It:

Internally: UTF-8 encoded byte array
Example: "Hello" โ†’ [48 65 6C 6C 6F] (hex bytes)

Real Examples:

-- User names 'Sarah Johnson' 'ๆŽๆ˜Ž' -- UTF-8 Chinese chars! 'Josรฉ Garcรญa ๐ŸŽ‰' -- Emojis OK! -- Email addresses 'sarah.j@example.com' -- Product descriptions 'Wireless Bluetooth Headphones with 30hr battery life' -- Blog post excerpt 'Learn Cassandra in 30 days...'

Use Cases:

  • โœ… Names (any language!)
  • โœ… Email addresses, URLs
  • โœ… Product descriptions
  • โœ… Comments, reviews, posts
  • โœ… JSON strings (store small JSON)
โœ…

BOOLEAN

BOOLEAN

Purpose: True or False!

Use Cases:

  • Is email verified?
  • Is order completed?
  • Is user active?
  • Agreed to terms?
is_verified BOOLEAN true / false
๐Ÿ“…

DATE

DATE

Purpose: Calendar dates (no time)

Format: YYYY-MM-DD

Use Cases:

  • Birthdays
  • Publication dates
  • Event dates
birthday DATE '2023-12-25'
โฐ

TIMESTAMP

TIMESTAMP

Purpose: Date AND exact time!

Use Cases:

  • Order placed time
  • Last login
  • Message sent time
created_at TIMESTAMP '2023-12-25 14:30:00'

๐Ÿ”ข Numeric Data Types

๐Ÿ”ข

INT

INT (32-bit)

Purpose: Whole numbers (no decimals)

Range: -2,147,483,648 to 2,147,483,647

Storage: 4 bytes (32 bits)

๐Ÿ“ฆ How Cassandra Stores It:

Binary format: 4 bytes
Example: 42 โ†’ 0x0000002A (hex)
Example: -100 โ†’ 0xFFFFFF9C (2's complement)

Real Examples:

-- Ages age INT 25, 30, 45 -- Product quantities stock_quantity INT 150 -- 150 units in stock 0 -- Out of stock -5 -- 5 units backordered -- Page numbers page_count INT 336 -- Book has 336 pages -- Score/Points game_score INT 9500 -- Player score -- Year birth_year INT 1995 -- Year born

Use Cases:

  • โœ… Age, year, count
  • โœ… Quantity, stock levels
  • โœ… Scores, points, ratings
  • โœ… Sequential IDs (small scale)
  • โŒ Money (use DECIMAL!)
  • โŒ Very large numbers (use BIGINT)
๐Ÿ’ฐ

DECIMAL

DECIMAL (Variable Precision)

Purpose: Exact decimals - PERFECT for money!

Precision: Arbitrary precision (no rounding errors)

Storage: Variable (depends on precision)

๐Ÿ“ฆ How Cassandra Stores It:

BigDecimal format: [scale][unscaled value]
Example: 19.99 โ†’ scale=2, value=1999
Stored as: 0x00 0x02 0x07 0xCF
NO rounding - 100% exact! โœ…

Real Money Examples:

-- Product prices price DECIMAL 19.99 -- Book price 999.95 -- Laptop price 0.99 -- App price -- Salary/Payments salary DECIMAL 75000.00 -- Annual salary 3250.50 -- Monthly payment -- Tax calculations tax_rate DECIMAL 0.075 -- 7.5% tax rate 0.0825 -- 8.25% sales tax -- Interest rates interest_rate DECIMAL 3.50 -- 3.5% APR -- Exact calculations work! 0.1 + 0.2 = 0.3 -- โœ… EXACT!

Use Cases:

  • โœ… ๐Ÿ’ต Money, prices, salaries
  • โœ… Tax calculations
  • โœ… Financial transactions
  • โœ… Accounting, invoices
  • โœ… Exact measurements
  • โญ Anytime precision matters!

โš ๏ธ NEVER use FLOAT for money!
FLOAT: 0.1 + 0.2 = 0.30000000000000004 โŒ

๐Ÿ“Š

BIGINT

BIGINT

Purpose: VERY large numbers

Use Cases:

  • Timestamps (ms)
  • Global counters
  • Large IDs
timestamp_ms BIGINT 1704110400000
๐ŸŽฏ

FLOAT

FLOAT

Purpose: Approximate decimals

Warning: May have rounding!

Use Cases:

  • GPS coordinates
  • Temperature
  • Scientific data
latitude FLOAT 37.7749

Money: NEVER use FLOAT!

โŒ WRONG:

price FLOAT -- BAD! Has rounding errors 19.99 becomes 19.989999...

โœ… CORRECT:

price DECIMAL -- GOOD! Exact precision 19.99 stays exactly 19.99

๐Ÿ†” UUID Types

๐Ÿ”‘

UUID

UUID (Version 4)

Purpose: Globally unique random identifier

Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (36 chars)

Storage: 16 bytes (128 bits)

Uniqueness: 340 undecillion possible values!

๐Ÿ“ฆ How Cassandra Stores It:

Binary: 128-bit (16 bytes) number
Display: 550e8400-e29b-41d4-a716-446655440000
Internal: [55 0E 84 00 E2 9B 41 D4 A7 16 44 66 55 44 00 00]

Real Examples:

-- Generate new UUID INSERT INTO users (user_id, name) VALUES (uuid(), 'Sarah'); -- Example UUIDs generated: 550e8400-e29b-41d4-a716-446655440000 7f8a9b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c a1b2c3d4-e5f6-4789-a1b2-c3d4e5f67890 -- Use in queries SELECT * FROM users WHERE user_id = 550e8400-e29b-41d4-a716-446655440000; -- Table with UUID PK CREATE TABLE orders ( order_id UUID PRIMARY KEY, user_id UUID, product_id UUID, total DECIMAL );

Use Cases:

  • โœ… Primary keys (distributed systems!)
  • โœ… User IDs
  • โœ… Order IDs, Transaction IDs
  • โœ… Session IDs, API keys
  • โœ… Any globally unique identifier

โœจ Why UUID is amazing:
โ€ข Generate IDs on any node - no coordination!
โ€ข Collision probability: 1 in 340 undecillion ๐Ÿคฏ
โ€ข Perfect for distributed systems

โฐ

TIMEUUID

TIMEUUID (Version 1)

Purpose: UUID with embedded timestamp!

Benefit: Automatically sortable by creation time

Storage: 16 bytes (128 bits) - same as UUID

Magic: Extract timestamp from the ID itself!

๐Ÿ“ฆ How Cassandra Stores It:

Structure: [timestamp][clock_seq][node_id]
Example: d2177dd0-eaa2-11de-a572-001b779c76e3
โ€ข First 60 bits: timestamp (100-nanosecond intervals)
โ€ข Sorted chronologically automatically! ๐ŸŽฏ

Real Examples:

-- Generate TIMEUUID (now) INSERT INTO messages (id, text, sender) VALUES (now(), 'Hello!', 'Sarah'); -- Messages automatically sorted by time! SELECT * FROM messages ORDER BY id DESC -- Newest first! -- Extract timestamp from TIMEUUID SELECT id, dateOf(id), text FROM messages; -- Returns: 2024-01-15 10:30:25 -- Query by time range SELECT * FROM events WHERE event_id > minTimeuuid('2024-01-01') AND event_id < maxTimeuuid('2024-01-31'); -- Chat app example CREATE TABLE chat_messages ( room_id UUID, message_id TIMEUUID, sender TEXT, content TEXT, PRIMARY KEY (room_id, message_id) ) WITH CLUSTERING ORDER BY (message_id DESC); -- Auto-sorted by time! ๐ŸŽ‰

Use Cases:

  • โœ… Chat messages (sorted by time)
  • โœ… Event logs, activity streams
  • โœ… Time-series data
  • โœ… Audit trails
  • โœ… IoT sensor readings
  • โญ Anything needing time + uniqueness!

๐ŸŒŸ TIMEUUID Benefits:
โ€ข Unique ID + Timestamp in one! 2-in-1!
โ€ข Automatic chronological sorting
โ€ข No separate created_at column needed
โ€ข Perfect for time-series data

๐Ÿ“ฆ Collection Types

๐Ÿ“‹

LIST

LIST<type>

Purpose: Ordered, allows duplicates

Use Cases:

  • Tags list
  • Shopping cart items
  • Recent searches
tags LIST<TEXT> ['fantasy', 'adventure']
๐ŸŽฏ

SET

SET<type>

Purpose: Unique values only

Use Cases:

  • Unique categories
  • Skills
  • Interests
skills SET<TEXT> {'java', 'python'}
๐Ÿ—บ๏ธ

MAP

MAP<key,value>

Purpose: Key-value pairs

Use Cases:

  • User preferences
  • Metadata
  • Attributes
prefs MAP<TEXT,TEXT> {'theme': 'dark'}

๐Ÿ–ฅ๏ธ Interactive Console

CQL Data Types Playground
Ready! Try the examples or write your own CREATE TABLE...

๐Ÿ”„ How to Choose the Right Data Type

Follow this decision tree to pick the perfect type every time!

Data Type Decision Tree What kind of data? Text/String? TEXT / VARCHAR Names, emails, descriptions UTF-8, up to 2GB Number? Which kind? ๐Ÿ’ฐ Money โ†’ DECIMAL ๐Ÿ”ข Whole โ†’ INT/BIGINT ๐Ÿ“Š Approx โ†’ FLOAT/DOUBLE ๐Ÿ“ˆ Counter โ†’ COUNTER True/False? BOOLEAN is_active, is_verified Only true or false Date/Time? Which precision? ๐Ÿ“… Date only โ†’ DATE โฐ Date + Time โ†’ TIMESTAMP Unique ID? Need time sorting? โŒ No โ†’ UUID โœ… Yes โ†’ TIMEUUID Multiple values? Which type? ๐Ÿ“‹ Ordered, duplicates OK โ†’ LIST ๐ŸŽฏ Unique values โ†’ SET ๐Ÿ—บ๏ธ Key-value pairs โ†’ MAP ๐ŸŽญ Complex structure โ†’ UDT

๐Ÿ’ผ Interview Questions

1 When should you use DECIMAL vs FLOAT? โ–ผ

Answer:

Use DECIMAL when:

  • ๐Ÿ’ฐ Storing money (prices, salaries, taxes)
  • Exact precision required
  • No rounding errors acceptable
  • Financial calculations

Use FLOAT when:

  • Scientific calculations (acceptable approximation)
  • GPS coordinates
  • Temperature readings
  • Statistical data where tiny errors OK

Key Insight: FLOAT can have rounding errors like 19.99 becoming 19.989999. DECIMAL is EXACT - perfect for money!

2 UUID vs TIMEUUID - when to use which? โ–ผ

Answer:

Use UUID when:

  • Just need unique ID
  • No time-based sorting needed
  • User IDs, Product IDs
  • Session tokens

Use TIMEUUID when:

  • Need automatic time-based sorting
  • Messages, Events, Logs
  • Want to extract timestamp from ID
  • Time-series data

Example: Chat app messages use TIMEUUID so messages automatically sort by time!

3 What's the difference between LIST and SET? โ–ผ

Answer:

LIST:

  • โœ… Ordered (maintains insertion order)
  • โœ… Allows duplicates
  • Use for: Shopping cart, recent searches, to-do items

SET:

  • โŒ Unordered
  • โŒ NO duplicates (automatically removes)
  • Use for: Unique tags, skills, categories
-- LIST allows duplicates ['apple', 'apple', 'banana'] -- Valid! -- SET removes duplicates {'apple', 'apple', 'banana'} -- Becomes: {'apple', 'banana'}
4 Can you change a column's data type after creation? โ–ผ

Answer: NO! (with rare exceptions)

Why not?

  • Data already stored in old format
  • Converting could lose data or cause errors
  • Cassandra prioritizes data safety

Solution if you MUST change:

  1. Add new column with correct type
  2. Migrate data (write script to copy/convert)
  3. Update application to use new column
  4. Drop old column (optional)
-- Add new column ALTER TABLE products ADD price_new DECIMAL; -- Migrate data UPDATE products SET price_new = price;

Lesson: Choose types carefully upfront! ๐ŸŽฏ

5 What's a COUNTER and how is it special? โ–ผ

Answer:

COUNTER is a special type that can ONLY be incremented or decremented - you cannot set it directly!

Special Rules:

  • โŒ Cannot use INSERT (must use UPDATE)
  • โœ… Can only do += or -= operations
  • Perfect for: page views, likes, downloads
-- Create counter table CREATE TABLE page_stats ( page_id TEXT PRIMARY KEY, view_count COUNTER ); -- โŒ WRONG - Cannot INSERT INSERT INTO page_stats (page_id, view_count) VALUES ('home', 0); -- ERROR! -- โœ… CORRECT - Use UPDATE UPDATE page_stats SET view_count = view_count + 1 WHERE page_id = 'home';

Why? COUNTER is distributed across nodes. Using += ensures consistency!

๐Ÿ“Š Data Type Comparison Matrix

Data Type Storage Size Range/Precision Best For Avoid For
TEXT Variable (UTF-8) Up to 2GB Names, descriptions Numbers, dates
INT 4 bytes -2B to +2B Quantities, ages Money, huge numbers
DECIMAL Variable Arbitrary precision ๐Ÿ’ฐ Money, finance Approximations OK
UUID 16 bytes 128-bit unique Primary keys, IDs Time-sorted data
TIMEUUID 16 bytes Timestamp + unique Messages, logs Random IDs

๐ŸŽ“ Chapter Summary

You now understand CQL data types!

  • Simple Types: TEXT, INT, BOOLEAN, DATE, TIMESTAMP
  • Numeric: INT, BIGINT, DECIMAL (money!), FLOAT, DOUBLE
  • UUID: Random IDs, TIMEUUID for time-sorted IDs
  • Collections: LIST (ordered), SET (unique), MAP (key-value)

๐ŸŽฏ Golden Rule: Use the RIGHT type for the RIGHT data!

๐Ÿข Real-World Production Examples

๐ŸŽต Spotify: Music Duration Storage Crisis

The Problem: Stored song duration as TEXT: "3:45", "4:12"

Issues:

  • Can't calculate total playlist duration
  • Can't sort by length
  • Can't find songs > 4 minutes

The Fix:

duration_seconds INT -- Store as 225 seconds instead of "3:45" -- Now can do: WHERE duration_seconds > 240

Result: Playlist calculations work! Sorting perfect! Users happy! ๐ŸŽ‰

๐Ÿ›’ Shopify: The FLOAT Price Disaster

The Problem: Used FLOAT for product prices

price FLOAT -- WRONG! 19.99 stored as 19.989999771118164

Impact: Customers charged $19.99, database showed $19.98 โ†’ Accounting nightmare!

The Fix:

price DECIMAL -- CORRECT! 19.99 stays exactly 19.99

Result: Accounting matched perfectly. CFO stopped panicking! ๐Ÿ’ฐ

Advertisement

Responsive Ad