SlideShare a Scribd company logo
1 of 79
Download to read offline
CQL Under the Hood 
Robbie Strickland
whoami? 
Robbie Strickland 
Software Development Manager 
@rs_atl
Target Audience 
• Veterans who don’t use or don’t understand CQL 
• Newcomers who only know CQL, but don’t know what’s happening 
underneath
Definitions 
• Thrift: legacy RPC protocol + code generation tool 
• batch_mutate, get_range_slices, multiget_slice, etc. 
• Deprecated in favor of native protocol 
• Native protocol: replacement for Thrift 
• Only works with CQL
Definitions 
• Storage rows: keys + columns as stored on disk 
• CQL rows: abstraction layer on top of storage rows 
• Not usually a direct mapping to storage rows 
• Make use of predefined schema 
• Data still sparse – no space used for null columns
In the Old Days … 
• Lots of clients with lots of APIs 
• No common language for describing schemas or queries 
• Steep learning curve
In the Old Days … 
• No cursors, so entire result set must fit in memory on client and server 
• Hard to add new features 
• Lag time between release of new features and client library adoption
Solution: CQL? 
SELECT * FROM mytable WHERE mykey = ‘foo’; 
WAT???!!!
Solution: CQL? 
Veterans 
“What happened to 
my NoSQL??!!”
Solution: CQL? 
Newbies 
“Sweet, SQL! I don’t 
have to learn 
anything new!”
Reality 
• Don’t panic 
• Thrift problems solved 
• You didn’t lose anything 
• Underlying storage is 
unchanged 
• Don’t get lazy 
• CQL is not SQL 
• You need to know what 
you’re doing 
• No, you can’t just index 
everything
Simple CQL 
CREATE TABLE Books (! 
title varchar,! 
author varchar,! 
year int,! 
PRIMARY KEY (title)! 
SELECT * FROM Books;! 
);! 
! 
INSERT INTO Books (title, author, year) ! 
VALUES ('Patriot Games', 'Tom Clancy', 1987);! 
INSERT INTO Books (title, author, year) ! 
VALUES ('Without Remorse', 'Tom Clancy', 1993);! 
! 
title | author | year! 
-----------------+------------+------! 
Without Remorse | Tom Clancy | 1993! 
Patriot Games | Tom Clancy | 1987!
Storage Rows 
[default@unknown] create keyspace Library;! 
[default@unknown] use Library;! 
[default@Library] create column family Books! 
...! with key_validation_class=UTF8Type! 
...! and comparator=UTF8Type! 
...! and default_validation_class=UTF8Type;! 
[default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! 
[default@Library] set Books['Patriot Games']['year'] = '1987';! 
[default@Library] list Books;! 
! 
RowKey: Patriot Games! 
=> (name=author, value=Tom Clancy, timestamp=1393102991499000)! 
=> (name=year, value=1987, timestamp=1393103015955000)!
Storage Rows 
[default@unknown] create keyspace Library;! 
[default@unknown] use Library;! 
[default@Library] create column family Books! 
...! with key_validation_class=UTF8Type! 
...! and comparator=UTF8Type! 
...! and default_validation_class=UTF8Type;! 
[default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! 
[default@Library] set Books['Patriot Games']['year'] = '1987';! 
[default@Library] list Books;! 
! 
RowKey: Patriot Games! 
=> (name=author, value=Tom Clancy, timestamp=1393102991499000)! 
=> (name=year, value=1987, timestamp=1393103015955000)! 
Random hash (no ordering)
Storage Rows 
[default@unknown] create keyspace Library;! 
[default@unknown] use Library;! 
[default@Library] create column family Books! 
...! with key_validation_class=UTF8Type! 
...! and comparator=UTF8Type! 
...! and default_validation_class=UTF8Type;! 
[default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! 
[default@Library] set Books['Patriot Games']['year'] = '1987';! 
[default@Library] list Books;! 
! 
Ordered by name 
RowKey: Patriot Games! 
=> (name=author, value=Tom Clancy, timestamp=1393102991499000)! 
=> (name=year, value=1987, timestamp=1393103015955000)!
Compound Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Compound Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
Partition key (row key) 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Compound Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
Clustering columns 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
== Composite Columns 
[default@Library] list authors;! 
! 
Partition key (row key) 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)!
== Composite Columns 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
Clustering columns
== Composite Columns 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
Ordered by name
Reversing Sort Order 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
) WITH CLUSTERING ORDER BY (year DESC);! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam!
Reversing Sort Order 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Composite Partition Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY ((name, year), title)! 
);! 
Composite partition key 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Composite Partition Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY ((name, year), title)! 
);! 
Clustering column 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
== Composite Keys 
[default@Library] list authors;! 
! 
Partition keys (row key) 
RowKey: Tom Clancy:1993! 
=> (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! 
=> (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! 
-------------------! 
RowKey: Tom Clancy:1987! 
=> (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! 
=> (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
== Composite Keys 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy:1993! 
=> (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! 
=> (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! 
-------------------! 
RowKey: Tom Clancy:1987! 
=> (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! 
=> (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)! 
Clustering column
Why This Matters 
• Queries must respect underlying storage, else they will either be slow or 
impossible 
• You have to know your partition key at query time 
• If you want fast multi-record queries, select a range, in storage order 
• With clustering columns, order matters
Example 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
) WITH CLUSTERING ORDER BY (year DESC);!
Example 
name | year | title | isbn | publisher! 
------------+------+-----------------------------+---------------+-----------! 
Tom Clancy | 1996 | Executive Orders | 0-399-13825-0 | Putnam! 
Tom Clancy | 1994 | Debt of Honor | 0-399-13826-1 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13927-0 | Putnam! 
Tom Clancy | 1991 | The Sum of All Fears | 0-399-12341-6 | Putnam! 
Tom Clancy | 1989 | Clear and Present Danger | 0-399-13341-1 | Putnam! 
Tom Clancy | 1988 | The Cardinal of the Kremlin | 0-399-13241-4 | Putnam! 
Tom Clancy | 1987 | Patriot Games | 0-399-13231-4 | Putnam! 
Tom Clancy | 1986 | Red Storm Rising | 0-399-13230-2 | Putnam! 
Tom Clancy | 1984 | The Hunt for Red October | 0-399-13251-1 | Putnam! 
!!
Query by Key 
SELECT * FROM authors 
WHERE name = ‘Tom Clancy’ 
(CL = QUORUM) 
RF = 3 
Tom 
Clancy 
Tom 
Clancy 
Tom 
Clancy
Query by Key 
Find partition key 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Query by Key 
Scan all columns in order 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Range Query 
SELECT * FROM authors 
WHERE name = ‘Tom Clancy’ 
AND year >= 1990 
(CL = QUORUM) 
Tom 
Clancy 
Tom 
Clancy 
Tom 
Clancy
Range Query 
Find partition key 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Range Query 
Scan until < 1990 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Querying Tail of Range 
SELECT * FROM authors 
WHERE name = ‘Tom Clancy’ 
AND year <= 1990 
(CL = QUORUM) 
Tom 
Clancy 
Tom 
Clancy 
Tom 
Clancy
Querying Tail of Range 
Find partition key 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Querying Tail of Range 
Scan all, 
then filter <= 1990 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Multiple Keys 
DK 
DK 
MG 
MG 
TC 
MG 
TC 
TC 
DK 
SELECT * FROM authors 
WHERE name IN 
(‘Tom Clancy’, 
‘Dean Koontz’, 
‘Malcolm Gladwell’) 
(CL = QUORUM)
Lessons Learned 
• Sequential == fast 
• Query by key / clustering column (range) == Sequential 
• Multi-key query often == lots of nodes 
• Write in the intended read order
Collections 
• Sets: unordered, unique 
• Lists: ordered, allow duplicates 
• Maps: key/value pairs – can be a good substitute for dynamic columns 
• Max 64k items, 64k per item 
• Always returns entire collection
Sets 
CREATE TABLE authors (! 
!name text,! 
!books set<text>,! 
PRIMARY KEY (name)! 
name | books! 
------------+--------------------------------------! 
Tom Clancy | {'Patriot Games', 'Without Remorse'}! 
);! 
! 
INSERT INTO authors (name, books) ! 
VALUES ('Tom Clancy', {'Without Remorse', 'Patriot Games'});!
Sets 
RowKey: Tom Clancy! 
=> (name=books:50617472696f742047616d6573, value=, ...)! 
=> (name=books:576974686f75742052656d6f727365, value=, ...)! 
Set name 
Set item 
Empty value
Lists 
CREATE TABLE authors (! 
!name text,! 
!books list<text>,! 
PRIMARY KEY (name)! 
name | books! 
------------+--------------------------------------! 
Tom Clancy | ['Without Remorse’, 'Patriot Games']! 
);! 
! 
INSERT INTO authors (name, books) ! 
VALUES ('Tom Clancy', ['Without Remorse', 'Patriot Games']);!
Lists 
RowKey: Tom Clancy! 
=> (name=books:d36de8b0305011e4a0dddbbeade718be, value=576974686f75742052656d6f727365, ...)! 
=> (name=books:d36de8b1305011e4a0dddbbeade718be, value=50617472696f742047616d6573, ...)! 
List name 
Ordering ID 
List item
Maps 
CREATE TABLE authors (! 
!name text,! 
!books map<text, int>,! 
PRIMARY KEY (name)! 
name | books! 
------------+-------------------------------------------------! 
Tom Clancy | {'Patriot Games': 1987, 'Without Remorse': 1993}! 
);! 
! 
INSERT INTO authors (name, books) ! 
VALUES ('Tom Clancy', ! 
{'Without Remorse' : 1993, 'Patriot Games' : 1987});!
Maps 
RowKey: Tom Clancy! 
=> (name=books:50617472696f742047616d6573, value=000007c3, ...)! 
=> (name=books:576974686f75742052656d6f727365, value=000007c9, ...)! 
Map name 
Map key 
Map value
Indices 
CREATE INDEX author_publisher! 
ON author (publisher);!
Indices 
• Allow query by value in certain cases 
• Partitioned based on row key of indexed table 
• Are updated atomically along with the data being inserted 
• Must be low cardinality, or it won’t scale well (to large cluster sizes) 
• But not too low, or it’s sort of pointless
Index Distribution 
Node 1 
Authors 
“Tom Clancy” : “Putnam”! 
“Mark Twain” : “Putnam”! 
! 
Index 
“Putnam” : “Tom Clancy”! 
“Putnam” : “Mark Twain”! 
! 
Node 2 
Authors 
“Mark Twain” : “Putnam”! 
“Dan Brown” : “Putnam”! 
! 
Index 
“Putnam” : “Mark Twain”! 
“Putnam” : “Dan Brown”! 
! 
Node 3 
Authors 
“Dan Brown” : “Putnam” 
“Tom Clancy” : “Putnam”! 
! 
Index 
“Putnam” : “Dan Brown”! 
“Putnam” : “Tom Clancy”! 
! 
Index key == indexed column value
Index Distribution 
Node 1 
Authors 
“Tom Clancy” : “Putnam”! 
“Mark Twain” : “Putnam”! 
! 
Index 
“Putnam” : “Tom Clancy”! 
“Putnam” : “Mark Twain”! 
! 
Node 2 
Authors 
“Mark Twain” : “Putnam”! 
“Dan Brown” : “Putnam”! 
! 
Index 
“Putnam” : “Mark Twain”! 
“Putnam” : “Dan Brown”! 
! 
Node 3 
Authors 
“Dan Brown” : “Putnam” 
“Tom Clancy” : “Putnam”! 
! 
Index 
“Putnam” : “Dan Brown”! 
“Putnam” : “Tom Clancy”! 
! 
… but node distribution based on original table key
Querying by Value 
pub idx 
pub idx 
pub idx pub idx 
pub idx 
pub idx 
SELECT * FROM authors 
WHERE publisher = ‘Putnam’ 
(CL = QUORUM)
Deletes 
DELETE FROM authors WHERE name = 'Tom Clancy';! 
! 
INSERT INTO authors (title, name) 
VALUES ('Patriot Games', 'Tom Clancy') 
USING TTL 86400;! 
! 
INSERT INTO authors (title, name, year) 
VALUES ('Patriot Games', 'Tom Clancy', null);! 
! 
UPDATE authors SET publisher = null 
WHERE name = 'Tom Clancy';! 
!
Deletes 
• Log-structured storage, so writes are immutable 
• Deletes create tombstones, one for each deleted column 
• Cassandra must read the tombstones to make sure it doesn’t revive 
deleted data 
• Lots of deletes is an anti-pattern
Missing Columns 
INSERT INTO authors (title, name, year)! 
VALUES ('Without Remorse', 'Tom Clancy', 1993);! 
! 
name | year | title | isbn | publisher! 
------------+------+-----------------+------+-----------! 
Tom Clancy | 1993 | Without Remorse | null | null! 
! 
RowKey: Tom Clancy! 
=> (name=1993:Without Remorse:, value=, timestamp=1409936754170000)!
Missing Columns 
activity | timestamp | source | source_elapsed! 
---------------------------------------------------------------------------+--------------+-----------+----------------! 
execute_cql3_query | 11:51:55,975 | 127.0.0.1 | 0! 
Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:51:55,975 | 127.0.0.1 | 47! 
Preparing statement | 11:51:55,975 | 127.0.0.1 | 105! 
Executing single-partition query on authors | 11:51:55,975 | 127.0.0.1 | 307! 
Acquiring sstable references | 11:51:55,975 | 127.0.0.1 | 315! 
Merging memtable tombstones | 11:51:55,975 | 127.0.0.1 | 328! 
Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:51:55,975 | 127.0.0.1 | 374! 
Merging data from memtables and 0 sstables | 11:51:55,975 | 127.0.0.1 | 383! 
Read 1 live and 0 tombstoned cells | 11:51:55,975 | 127.0.0.1 | 420! 
Request complete | 11:51:55,975 | 127.0.0.1 | 585! 
Only 1 read required
Null Columns 
INSERT INTO authors (title, name, year, isbn, publisher) 
VALUES ('Without Remorse', 'Tom Clancy', 1993, null, null);! 
! 
name | year | title | isbn | publisher! 
------------+------+-----------------+------+-----------! 
Tom Clancy | 1993 | Without Remorse | null | null!
Null Columns 
activity | timestamp | source | source_elapsed! 
---------------------------------------------------------------------------+--------------+-----------+----------------! 
execute_cql3_query | 11:57:31,623 | 127.0.0.1 | 0! 
Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:57:31,623 | 127.0.0.1 | 41! 
Preparing statement | 11:57:31,623 | 127.0.0.1 | 101! 
Executing single-partition query on authors | 11:57:31,623 | 127.0.0.1 | 532! 
Acquiring sstable references | 11:57:31,623 | 127.0.0.1 | 544! 
Merging memtable tombstones | 11:57:31,623 | 127.0.0.1 | 571! 
Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:57:31,623 | 127.0.0.1 | 596! 
Merging data from memtables and 0 sstables | 11:57:31,623 | 127.0.0.1 | 605! 
Read 1 live and 2 tombstoned cells | 11:57:31,624 | 127.0.0.1 | 669! 
Request complete | 11:57:31,623 | 127.0.0.1 | 777! 
3 reads required!
Why Queries Fail 
SELECT name FROM authors WHERE title = 'Patriot Games';! 
Bad Request: PRIMARY KEY part title cannot be 
restricted (preceding part year is either not 
restricted or by a non-EQ relation)!
Why Queries Fail 
• Failure to provide the full partition key 
• Querying by value without an index 
• Misunderstanding clustering columns
Missing Key Parts 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY ((name, year), title)! 
);! 
! 
! 
SELECT name FROM authors WHERE title
Missing Key Parts 
[default@Library] list authors;! 
! 
Partition keys (row key) 
RowKey: Tom Clancy:1993! 
=> (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! 
=> (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! 
-------------------! 
RowKey: Tom Clancy:1987! 
=> (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! 
=> (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
Missing Key Parts 
SELECT * FROM authors WHERE name = 'Tom Clancy’;! 
Bad Request: Partition key part year must be restricted 
since preceding part is!
Missing Key Parts 
SELECT * FROM authors WHERE year = 1987;! 
Bad Request: partition key part year cannot be 
restricted (preceding part name is either not 
restricted or by a non-EQ relation)!
Missing Key Parts 
SELECT * FROM authors WHERE year >= 1987;! 
Bad Request: partition key part year cannot be 
restricted (preceding part name is either not 
restricted or by a non-EQ relation)!
Missing Key Parts 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy' and year >= 1987;! 
! 
Bad Request: Only EQ and IN relation are supported on 
the partition key (unless you use the token() function)!
Querying by Value 
SELECT * FROM authors WHERE isbn = '0-399-13241-4';! 
Bad Request: No indexed columns present in by-columns 
clause with Equal operator!
Querying Clustering Columns 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
! 
! 
SELECT name FROM authors WHERE
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
Clustering columns
Querying Clustering Columns 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy’! 
AND year = 1993;! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
Querying Clustering Columns 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy’! 
AND year <= 1993;! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
Querying Clustering Columns 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy’! 
AND title = 'Patriot Games';! 
! 
Bad Request: PRIMARY KEY part title cannot be restricted 
(preceding part year is either not restricted or by a 
non-EQ relation)! 
!!
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
?
Summary 
• Stop using Thrift; use CQL instead 
• … but know what your model/query is doing
Thanks! 
Robbie Strickland 
Software Development Manager 
@rs_atl
CQL Under the Hood

More Related Content

What's hot

ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!Guido Schmutz
 
Airflow presentation
Airflow presentationAirflow presentation
Airflow presentationIlias Okacha
 
Improving Apache Spark's Reliability with DataSourceV2
Improving Apache Spark's Reliability with DataSourceV2Improving Apache Spark's Reliability with DataSourceV2
Improving Apache Spark's Reliability with DataSourceV2Databricks
 
Chapter 5 design of keyvalue databses from nosql for mere mortals
Chapter 5 design of keyvalue databses from nosql for mere mortalsChapter 5 design of keyvalue databses from nosql for mere mortals
Chapter 5 design of keyvalue databses from nosql for mere mortalsnehabsairam
 
The Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication TutorialThe Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication TutorialJean-François Gagné
 
MySQL NDB Cluster 101
MySQL NDB Cluster 101MySQL NDB Cluster 101
MySQL NDB Cluster 101Bernd Ocklin
 
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...DataStax
 
10 things, an Oracle DBA should care about when moving to PostgreSQL
10 things, an Oracle DBA should care about when moving to PostgreSQL10 things, an Oracle DBA should care about when moving to PostgreSQL
10 things, an Oracle DBA should care about when moving to PostgreSQLPostgreSQL-Consulting
 
MariaDB Server Performance Tuning & Optimization
MariaDB Server Performance Tuning & OptimizationMariaDB Server Performance Tuning & Optimization
MariaDB Server Performance Tuning & OptimizationMariaDB plc
 
Citus Architecture: Extending Postgres to Build a Distributed Database
Citus Architecture: Extending Postgres to Build a Distributed DatabaseCitus Architecture: Extending Postgres to Build a Distributed Database
Citus Architecture: Extending Postgres to Build a Distributed DatabaseOzgun Erdogan
 
No SQL- The Future Of Data Storage
No SQL- The Future Of Data StorageNo SQL- The Future Of Data Storage
No SQL- The Future Of Data StorageBethmi Gunasekara
 
Schema-on-Read vs Schema-on-Write
Schema-on-Read vs Schema-on-WriteSchema-on-Read vs Schema-on-Write
Schema-on-Read vs Schema-on-WriteAmr Awadallah
 
An Overview of Apache Cassandra
An Overview of Apache CassandraAn Overview of Apache Cassandra
An Overview of Apache CassandraDataStax
 
Common Strategies for Improving Performance on Your Delta Lakehouse
Common Strategies for Improving Performance on Your Delta LakehouseCommon Strategies for Improving Performance on Your Delta Lakehouse
Common Strategies for Improving Performance on Your Delta LakehouseDatabricks
 
Scylla Compaction Strategies
Scylla Compaction StrategiesScylla Compaction Strategies
Scylla Compaction StrategiesNadav Har'El
 

What's hot (20)

ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!
 
Airflow presentation
Airflow presentationAirflow presentation
Airflow presentation
 
Improving Apache Spark's Reliability with DataSourceV2
Improving Apache Spark's Reliability with DataSourceV2Improving Apache Spark's Reliability with DataSourceV2
Improving Apache Spark's Reliability with DataSourceV2
 
Chapter 5 design of keyvalue databses from nosql for mere mortals
Chapter 5 design of keyvalue databses from nosql for mere mortalsChapter 5 design of keyvalue databses from nosql for mere mortals
Chapter 5 design of keyvalue databses from nosql for mere mortals
 
Cloud arch patterns
Cloud arch patternsCloud arch patterns
Cloud arch patterns
 
The Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication TutorialThe Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication Tutorial
 
MySQL NDB Cluster 101
MySQL NDB Cluster 101MySQL NDB Cluster 101
MySQL NDB Cluster 101
 
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
 
10 things, an Oracle DBA should care about when moving to PostgreSQL
10 things, an Oracle DBA should care about when moving to PostgreSQL10 things, an Oracle DBA should care about when moving to PostgreSQL
10 things, an Oracle DBA should care about when moving to PostgreSQL
 
MariaDB Server Performance Tuning & Optimization
MariaDB Server Performance Tuning & OptimizationMariaDB Server Performance Tuning & Optimization
MariaDB Server Performance Tuning & Optimization
 
Get to know PostgreSQL!
Get to know PostgreSQL!Get to know PostgreSQL!
Get to know PostgreSQL!
 
Using galera replication to create geo distributed clusters on the wan
Using galera replication to create geo distributed clusters on the wanUsing galera replication to create geo distributed clusters on the wan
Using galera replication to create geo distributed clusters on the wan
 
Citus Architecture: Extending Postgres to Build a Distributed Database
Citus Architecture: Extending Postgres to Build a Distributed DatabaseCitus Architecture: Extending Postgres to Build a Distributed Database
Citus Architecture: Extending Postgres to Build a Distributed Database
 
No SQL- The Future Of Data Storage
No SQL- The Future Of Data StorageNo SQL- The Future Of Data Storage
No SQL- The Future Of Data Storage
 
Schema-on-Read vs Schema-on-Write
Schema-on-Read vs Schema-on-WriteSchema-on-Read vs Schema-on-Write
Schema-on-Read vs Schema-on-Write
 
An Overview of Apache Cassandra
An Overview of Apache CassandraAn Overview of Apache Cassandra
An Overview of Apache Cassandra
 
Common Strategies for Improving Performance on Your Delta Lakehouse
Common Strategies for Improving Performance on Your Delta LakehouseCommon Strategies for Improving Performance on Your Delta Lakehouse
Common Strategies for Improving Performance on Your Delta Lakehouse
 
Scylla Compaction Strategies
Scylla Compaction StrategiesScylla Compaction Strategies
Scylla Compaction Strategies
 
Galera Cluster DDL and Schema Upgrades 220217
Galera Cluster DDL and Schema Upgrades 220217Galera Cluster DDL and Schema Upgrades 220217
Galera Cluster DDL and Schema Upgrades 220217
 
PostgreSQL
PostgreSQLPostgreSQL
PostgreSQL
 

Viewers also liked

DataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clauseDataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clauseDataStax Academy
 
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...DataStax
 
Understanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache CassandraUnderstanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache CassandraDataStax
 
Cql – cassandra query language
Cql – cassandra query languageCql – cassandra query language
Cql – cassandra query languageCourtney Robinson
 
Cassandra internals
Cassandra internalsCassandra internals
Cassandra internalsnarsiman
 
CQL: SQL In Cassandra
CQL: SQL In CassandraCQL: SQL In Cassandra
CQL: SQL In CassandraEric Evans
 
Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0J.B. Langston
 
Hardening cassandra q2_2016
Hardening cassandra q2_2016Hardening cassandra q2_2016
Hardening cassandra q2_2016zznate
 
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...DataStax Academy
 
Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015Robbie Strickland
 
Hadoop 2.0 - The Next Level
Hadoop 2.0 - The Next LevelHadoop 2.0 - The Next Level
Hadoop 2.0 - The Next LevelSascha Dittmann
 
Cassandra presentation at NoSQL
Cassandra presentation at NoSQLCassandra presentation at NoSQL
Cassandra presentation at NoSQLEvan Weaver
 
Introduction to Apache Cassandra
Introduction to Apache CassandraIntroduction to Apache Cassandra
Introduction to Apache CassandraRobert Stupp
 
Overview of DataStax OpsCenter
Overview of DataStax OpsCenterOverview of DataStax OpsCenter
Overview of DataStax OpsCenterDataStax
 

Viewers also liked (20)

DataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clauseDataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clause
 
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
 
Understanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache CassandraUnderstanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache Cassandra
 
Cassandra @ Yahoo Japan | Cassandra Summit 2016
Cassandra @ Yahoo Japan | Cassandra Summit 2016Cassandra @ Yahoo Japan | Cassandra Summit 2016
Cassandra @ Yahoo Japan | Cassandra Summit 2016
 
Cql – cassandra query language
Cql – cassandra query languageCql – cassandra query language
Cql – cassandra query language
 
NoSQL Essentials: Cassandra
NoSQL Essentials: CassandraNoSQL Essentials: Cassandra
NoSQL Essentials: Cassandra
 
Cassandra internals
Cassandra internalsCassandra internals
Cassandra internals
 
Cassandra Summit 2016 注目セッション報告
Cassandra Summit 2016 注目セッション報告Cassandra Summit 2016 注目セッション報告
Cassandra Summit 2016 注目セッション報告
 
Intro to Cassandra
Intro to CassandraIntro to Cassandra
Intro to Cassandra
 
CQL: SQL In Cassandra
CQL: SQL In CassandraCQL: SQL In Cassandra
CQL: SQL In Cassandra
 
Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0
 
Hardening cassandra q2_2016
Hardening cassandra q2_2016Hardening cassandra q2_2016
Hardening cassandra q2_2016
 
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
 
Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015
 
Hadoop 2.0 - The Next Level
Hadoop 2.0 - The Next LevelHadoop 2.0 - The Next Level
Hadoop 2.0 - The Next Level
 
Cassandra presentation at NoSQL
Cassandra presentation at NoSQLCassandra presentation at NoSQL
Cassandra presentation at NoSQL
 
Become a super modeler
Become a super modelerBecome a super modeler
Become a super modeler
 
Global Netflix Platform
Global Netflix PlatformGlobal Netflix Platform
Global Netflix Platform
 
Introduction to Apache Cassandra
Introduction to Apache CassandraIntroduction to Apache Cassandra
Introduction to Apache Cassandra
 
Overview of DataStax OpsCenter
Overview of DataStax OpsCenterOverview of DataStax OpsCenter
Overview of DataStax OpsCenter
 

More from DataStax Academy

Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftForrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftDataStax Academy
 
Introduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseIntroduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseDataStax Academy
 
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraIntroduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraDataStax Academy
 
Cassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsCassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsDataStax Academy
 
Cassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingCassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingDataStax Academy
 
Cassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackCassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackDataStax Academy
 
Data Modeling for Apache Cassandra
Data Modeling for Apache CassandraData Modeling for Apache Cassandra
Data Modeling for Apache CassandraDataStax Academy
 
Production Ready Cassandra
Production Ready CassandraProduction Ready Cassandra
Production Ready CassandraDataStax Academy
 
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonCassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonDataStax Academy
 
Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1DataStax Academy
 
Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2DataStax Academy
 
Standing Up Your First Cluster
Standing Up Your First ClusterStanding Up Your First Cluster
Standing Up Your First ClusterDataStax Academy
 
Real Time Analytics with Dse
Real Time Analytics with DseReal Time Analytics with Dse
Real Time Analytics with DseDataStax Academy
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraDataStax Academy
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseDataStax Academy
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraDataStax Academy
 

More from DataStax Academy (20)

Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftForrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
 
Introduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseIntroduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph Database
 
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraIntroduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
 
Cassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsCassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart Labs
 
Cassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingCassandra 3.0 Data Modeling
Cassandra 3.0 Data Modeling
 
Cassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackCassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stack
 
Data Modeling for Apache Cassandra
Data Modeling for Apache CassandraData Modeling for Apache Cassandra
Data Modeling for Apache Cassandra
 
Coursera Cassandra Driver
Coursera Cassandra DriverCoursera Cassandra Driver
Coursera Cassandra Driver
 
Production Ready Cassandra
Production Ready CassandraProduction Ready Cassandra
Production Ready Cassandra
 
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonCassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
 
Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1
 
Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2
 
Standing Up Your First Cluster
Standing Up Your First ClusterStanding Up Your First Cluster
Standing Up Your First Cluster
 
Real Time Analytics with Dse
Real Time Analytics with DseReal Time Analytics with Dse
Real Time Analytics with Dse
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache Cassandra
 
Cassandra Core Concepts
Cassandra Core ConceptsCassandra Core Concepts
Cassandra Core Concepts
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax Enterprise
 
Bad Habits Die Hard
Bad Habits Die Hard Bad Habits Die Hard
Bad Habits Die Hard
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache Cassandra
 
Advanced Cassandra
Advanced CassandraAdvanced Cassandra
Advanced Cassandra
 

Recently uploaded

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

CQL Under the Hood

  • 1. CQL Under the Hood Robbie Strickland
  • 2. whoami? Robbie Strickland Software Development Manager @rs_atl
  • 3. Target Audience • Veterans who don’t use or don’t understand CQL • Newcomers who only know CQL, but don’t know what’s happening underneath
  • 4. Definitions • Thrift: legacy RPC protocol + code generation tool • batch_mutate, get_range_slices, multiget_slice, etc. • Deprecated in favor of native protocol • Native protocol: replacement for Thrift • Only works with CQL
  • 5. Definitions • Storage rows: keys + columns as stored on disk • CQL rows: abstraction layer on top of storage rows • Not usually a direct mapping to storage rows • Make use of predefined schema • Data still sparse – no space used for null columns
  • 6. In the Old Days … • Lots of clients with lots of APIs • No common language for describing schemas or queries • Steep learning curve
  • 7. In the Old Days … • No cursors, so entire result set must fit in memory on client and server • Hard to add new features • Lag time between release of new features and client library adoption
  • 8. Solution: CQL? SELECT * FROM mytable WHERE mykey = ‘foo’; WAT???!!!
  • 9. Solution: CQL? Veterans “What happened to my NoSQL??!!”
  • 10. Solution: CQL? Newbies “Sweet, SQL! I don’t have to learn anything new!”
  • 11. Reality • Don’t panic • Thrift problems solved • You didn’t lose anything • Underlying storage is unchanged • Don’t get lazy • CQL is not SQL • You need to know what you’re doing • No, you can’t just index everything
  • 12. Simple CQL CREATE TABLE Books (! title varchar,! author varchar,! year int,! PRIMARY KEY (title)! SELECT * FROM Books;! );! ! INSERT INTO Books (title, author, year) ! VALUES ('Patriot Games', 'Tom Clancy', 1987);! INSERT INTO Books (title, author, year) ! VALUES ('Without Remorse', 'Tom Clancy', 1993);! ! title | author | year! -----------------+------------+------! Without Remorse | Tom Clancy | 1993! Patriot Games | Tom Clancy | 1987!
  • 13. Storage Rows [default@unknown] create keyspace Library;! [default@unknown] use Library;! [default@Library] create column family Books! ...! with key_validation_class=UTF8Type! ...! and comparator=UTF8Type! ...! and default_validation_class=UTF8Type;! [default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! [default@Library] set Books['Patriot Games']['year'] = '1987';! [default@Library] list Books;! ! RowKey: Patriot Games! => (name=author, value=Tom Clancy, timestamp=1393102991499000)! => (name=year, value=1987, timestamp=1393103015955000)!
  • 14. Storage Rows [default@unknown] create keyspace Library;! [default@unknown] use Library;! [default@Library] create column family Books! ...! with key_validation_class=UTF8Type! ...! and comparator=UTF8Type! ...! and default_validation_class=UTF8Type;! [default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! [default@Library] set Books['Patriot Games']['year'] = '1987';! [default@Library] list Books;! ! RowKey: Patriot Games! => (name=author, value=Tom Clancy, timestamp=1393102991499000)! => (name=year, value=1987, timestamp=1393103015955000)! Random hash (no ordering)
  • 15. Storage Rows [default@unknown] create keyspace Library;! [default@unknown] use Library;! [default@Library] create column family Books! ...! with key_validation_class=UTF8Type! ...! and comparator=UTF8Type! ...! and default_validation_class=UTF8Type;! [default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! [default@Library] set Books['Patriot Games']['year'] = '1987';! [default@Library] list Books;! ! Ordered by name RowKey: Patriot Games! => (name=author, value=Tom Clancy, timestamp=1393102991499000)! => (name=year, value=1987, timestamp=1393103015955000)!
  • 16. Compound Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 17. Compound Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! Partition key (row key) name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 18. Compound Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! Clustering columns name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 19. == Composite Columns [default@Library] list authors;! ! Partition key (row key) RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)!
  • 20. == Composite Columns [default@Library] list authors;! ! RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! Clustering columns
  • 21. == Composite Columns [default@Library] list authors;! ! RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! Ordered by name
  • 22. Reversing Sort Order CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! ) WITH CLUSTERING ORDER BY (year DESC);! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam!
  • 23. Reversing Sort Order [default@Library] list authors;! ! RowKey: Tom Clancy! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 24. Composite Partition Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY ((name, year), title)! );! Composite partition key name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 25. Composite Partition Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY ((name, year), title)! );! Clustering column name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 26. == Composite Keys [default@Library] list authors;! ! Partition keys (row key) RowKey: Tom Clancy:1993! => (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! => (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! -------------------! RowKey: Tom Clancy:1987! => (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! => (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
  • 27. == Composite Keys [default@Library] list authors;! ! RowKey: Tom Clancy:1993! => (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! => (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! -------------------! RowKey: Tom Clancy:1987! => (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! => (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)! Clustering column
  • 28. Why This Matters • Queries must respect underlying storage, else they will either be slow or impossible • You have to know your partition key at query time • If you want fast multi-record queries, select a range, in storage order • With clustering columns, order matters
  • 29. Example CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! ) WITH CLUSTERING ORDER BY (year DESC);!
  • 30. Example name | year | title | isbn | publisher! ------------+------+-----------------------------+---------------+-----------! Tom Clancy | 1996 | Executive Orders | 0-399-13825-0 | Putnam! Tom Clancy | 1994 | Debt of Honor | 0-399-13826-1 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13927-0 | Putnam! Tom Clancy | 1991 | The Sum of All Fears | 0-399-12341-6 | Putnam! Tom Clancy | 1989 | Clear and Present Danger | 0-399-13341-1 | Putnam! Tom Clancy | 1988 | The Cardinal of the Kremlin | 0-399-13241-4 | Putnam! Tom Clancy | 1987 | Patriot Games | 0-399-13231-4 | Putnam! Tom Clancy | 1986 | Red Storm Rising | 0-399-13230-2 | Putnam! Tom Clancy | 1984 | The Hunt for Red October | 0-399-13251-1 | Putnam! !!
  • 31. Query by Key SELECT * FROM authors WHERE name = ‘Tom Clancy’ (CL = QUORUM) RF = 3 Tom Clancy Tom Clancy Tom Clancy
  • 32. Query by Key Find partition key RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 33. Query by Key Scan all columns in order RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 34. Range Query SELECT * FROM authors WHERE name = ‘Tom Clancy’ AND year >= 1990 (CL = QUORUM) Tom Clancy Tom Clancy Tom Clancy
  • 35. Range Query Find partition key RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 36. Range Query Scan until < 1990 RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 37. Querying Tail of Range SELECT * FROM authors WHERE name = ‘Tom Clancy’ AND year <= 1990 (CL = QUORUM) Tom Clancy Tom Clancy Tom Clancy
  • 38. Querying Tail of Range Find partition key RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 39. Querying Tail of Range Scan all, then filter <= 1990 RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 40. Multiple Keys DK DK MG MG TC MG TC TC DK SELECT * FROM authors WHERE name IN (‘Tom Clancy’, ‘Dean Koontz’, ‘Malcolm Gladwell’) (CL = QUORUM)
  • 41. Lessons Learned • Sequential == fast • Query by key / clustering column (range) == Sequential • Multi-key query often == lots of nodes • Write in the intended read order
  • 42. Collections • Sets: unordered, unique • Lists: ordered, allow duplicates • Maps: key/value pairs – can be a good substitute for dynamic columns • Max 64k items, 64k per item • Always returns entire collection
  • 43. Sets CREATE TABLE authors (! !name text,! !books set<text>,! PRIMARY KEY (name)! name | books! ------------+--------------------------------------! Tom Clancy | {'Patriot Games', 'Without Remorse'}! );! ! INSERT INTO authors (name, books) ! VALUES ('Tom Clancy', {'Without Remorse', 'Patriot Games'});!
  • 44. Sets RowKey: Tom Clancy! => (name=books:50617472696f742047616d6573, value=, ...)! => (name=books:576974686f75742052656d6f727365, value=, ...)! Set name Set item Empty value
  • 45. Lists CREATE TABLE authors (! !name text,! !books list<text>,! PRIMARY KEY (name)! name | books! ------------+--------------------------------------! Tom Clancy | ['Without Remorse’, 'Patriot Games']! );! ! INSERT INTO authors (name, books) ! VALUES ('Tom Clancy', ['Without Remorse', 'Patriot Games']);!
  • 46. Lists RowKey: Tom Clancy! => (name=books:d36de8b0305011e4a0dddbbeade718be, value=576974686f75742052656d6f727365, ...)! => (name=books:d36de8b1305011e4a0dddbbeade718be, value=50617472696f742047616d6573, ...)! List name Ordering ID List item
  • 47. Maps CREATE TABLE authors (! !name text,! !books map<text, int>,! PRIMARY KEY (name)! name | books! ------------+-------------------------------------------------! Tom Clancy | {'Patriot Games': 1987, 'Without Remorse': 1993}! );! ! INSERT INTO authors (name, books) ! VALUES ('Tom Clancy', ! {'Without Remorse' : 1993, 'Patriot Games' : 1987});!
  • 48. Maps RowKey: Tom Clancy! => (name=books:50617472696f742047616d6573, value=000007c3, ...)! => (name=books:576974686f75742052656d6f727365, value=000007c9, ...)! Map name Map key Map value
  • 49. Indices CREATE INDEX author_publisher! ON author (publisher);!
  • 50. Indices • Allow query by value in certain cases • Partitioned based on row key of indexed table • Are updated atomically along with the data being inserted • Must be low cardinality, or it won’t scale well (to large cluster sizes) • But not too low, or it’s sort of pointless
  • 51. Index Distribution Node 1 Authors “Tom Clancy” : “Putnam”! “Mark Twain” : “Putnam”! ! Index “Putnam” : “Tom Clancy”! “Putnam” : “Mark Twain”! ! Node 2 Authors “Mark Twain” : “Putnam”! “Dan Brown” : “Putnam”! ! Index “Putnam” : “Mark Twain”! “Putnam” : “Dan Brown”! ! Node 3 Authors “Dan Brown” : “Putnam” “Tom Clancy” : “Putnam”! ! Index “Putnam” : “Dan Brown”! “Putnam” : “Tom Clancy”! ! Index key == indexed column value
  • 52. Index Distribution Node 1 Authors “Tom Clancy” : “Putnam”! “Mark Twain” : “Putnam”! ! Index “Putnam” : “Tom Clancy”! “Putnam” : “Mark Twain”! ! Node 2 Authors “Mark Twain” : “Putnam”! “Dan Brown” : “Putnam”! ! Index “Putnam” : “Mark Twain”! “Putnam” : “Dan Brown”! ! Node 3 Authors “Dan Brown” : “Putnam” “Tom Clancy” : “Putnam”! ! Index “Putnam” : “Dan Brown”! “Putnam” : “Tom Clancy”! ! … but node distribution based on original table key
  • 53. Querying by Value pub idx pub idx pub idx pub idx pub idx pub idx SELECT * FROM authors WHERE publisher = ‘Putnam’ (CL = QUORUM)
  • 54. Deletes DELETE FROM authors WHERE name = 'Tom Clancy';! ! INSERT INTO authors (title, name) VALUES ('Patriot Games', 'Tom Clancy') USING TTL 86400;! ! INSERT INTO authors (title, name, year) VALUES ('Patriot Games', 'Tom Clancy', null);! ! UPDATE authors SET publisher = null WHERE name = 'Tom Clancy';! !
  • 55. Deletes • Log-structured storage, so writes are immutable • Deletes create tombstones, one for each deleted column • Cassandra must read the tombstones to make sure it doesn’t revive deleted data • Lots of deletes is an anti-pattern
  • 56. Missing Columns INSERT INTO authors (title, name, year)! VALUES ('Without Remorse', 'Tom Clancy', 1993);! ! name | year | title | isbn | publisher! ------------+------+-----------------+------+-----------! Tom Clancy | 1993 | Without Remorse | null | null! ! RowKey: Tom Clancy! => (name=1993:Without Remorse:, value=, timestamp=1409936754170000)!
  • 57. Missing Columns activity | timestamp | source | source_elapsed! ---------------------------------------------------------------------------+--------------+-----------+----------------! execute_cql3_query | 11:51:55,975 | 127.0.0.1 | 0! Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:51:55,975 | 127.0.0.1 | 47! Preparing statement | 11:51:55,975 | 127.0.0.1 | 105! Executing single-partition query on authors | 11:51:55,975 | 127.0.0.1 | 307! Acquiring sstable references | 11:51:55,975 | 127.0.0.1 | 315! Merging memtable tombstones | 11:51:55,975 | 127.0.0.1 | 328! Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:51:55,975 | 127.0.0.1 | 374! Merging data from memtables and 0 sstables | 11:51:55,975 | 127.0.0.1 | 383! Read 1 live and 0 tombstoned cells | 11:51:55,975 | 127.0.0.1 | 420! Request complete | 11:51:55,975 | 127.0.0.1 | 585! Only 1 read required
  • 58. Null Columns INSERT INTO authors (title, name, year, isbn, publisher) VALUES ('Without Remorse', 'Tom Clancy', 1993, null, null);! ! name | year | title | isbn | publisher! ------------+------+-----------------+------+-----------! Tom Clancy | 1993 | Without Remorse | null | null!
  • 59. Null Columns activity | timestamp | source | source_elapsed! ---------------------------------------------------------------------------+--------------+-----------+----------------! execute_cql3_query | 11:57:31,623 | 127.0.0.1 | 0! Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:57:31,623 | 127.0.0.1 | 41! Preparing statement | 11:57:31,623 | 127.0.0.1 | 101! Executing single-partition query on authors | 11:57:31,623 | 127.0.0.1 | 532! Acquiring sstable references | 11:57:31,623 | 127.0.0.1 | 544! Merging memtable tombstones | 11:57:31,623 | 127.0.0.1 | 571! Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:57:31,623 | 127.0.0.1 | 596! Merging data from memtables and 0 sstables | 11:57:31,623 | 127.0.0.1 | 605! Read 1 live and 2 tombstoned cells | 11:57:31,624 | 127.0.0.1 | 669! Request complete | 11:57:31,623 | 127.0.0.1 | 777! 3 reads required!
  • 60. Why Queries Fail SELECT name FROM authors WHERE title = 'Patriot Games';! Bad Request: PRIMARY KEY part title cannot be restricted (preceding part year is either not restricted or by a non-EQ relation)!
  • 61. Why Queries Fail • Failure to provide the full partition key • Querying by value without an index • Misunderstanding clustering columns
  • 62. Missing Key Parts CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY ((name, year), title)! );! ! ! SELECT name FROM authors WHERE title
  • 63. Missing Key Parts [default@Library] list authors;! ! Partition keys (row key) RowKey: Tom Clancy:1993! => (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! => (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! -------------------! RowKey: Tom Clancy:1987! => (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! => (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
  • 64. Missing Key Parts SELECT * FROM authors WHERE name = 'Tom Clancy’;! Bad Request: Partition key part year must be restricted since preceding part is!
  • 65. Missing Key Parts SELECT * FROM authors WHERE year = 1987;! Bad Request: partition key part year cannot be restricted (preceding part name is either not restricted or by a non-EQ relation)!
  • 66. Missing Key Parts SELECT * FROM authors WHERE year >= 1987;! Bad Request: partition key part year cannot be restricted (preceding part name is either not restricted or by a non-EQ relation)!
  • 67. Missing Key Parts SELECT * FROM authors ! WHERE name = 'Tom Clancy' and year >= 1987;! ! Bad Request: Only EQ and IN relation are supported on the partition key (unless you use the token() function)!
  • 68. Querying by Value SELECT * FROM authors WHERE isbn = '0-399-13241-4';! Bad Request: No indexed columns present in by-columns clause with Equal operator!
  • 69. Querying Clustering Columns CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! ! ! SELECT name FROM authors WHERE
  • 70. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! Clustering columns
  • 71. Querying Clustering Columns SELECT * FROM authors ! WHERE name = 'Tom Clancy’! AND year = 1993;! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 72. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
  • 73. Querying Clustering Columns SELECT * FROM authors ! WHERE name = 'Tom Clancy’! AND year <= 1993;! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 74. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
  • 75. Querying Clustering Columns SELECT * FROM authors ! WHERE name = 'Tom Clancy’! AND title = 'Patriot Games';! ! Bad Request: PRIMARY KEY part title cannot be restricted (preceding part year is either not restricted or by a non-EQ relation)! !!
  • 76. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! ?
  • 77. Summary • Stop using Thrift; use CQL instead • … but know what your model/query is doing
  • 78. Thanks! Robbie Strickland Software Development Manager @rs_atl