00:00

MySQL Vs Cassandra

Last updated: 4 min read

MySQL is a relational database built around tables, joins and ACID transactions. Apache Cassandra is a distributed wide-column NoSQL database built for massive write volumes and always-on availability across data centres. They solve different problems, and many large companies run both.

1. Overview

MySQLApache Cassandra
TypeRelational (RDBMS)Distributed wide-column store
OriginMySQL AB, 1995; now OracleFacebook, 2008; Apache project since 2009
LicenceGPL v2 / commercialApache License 2.0
Query languageSQLCQL (Cassandra Query Language), SQL-like
ArchitectureSingle server, or source + replicas / Group ReplicationMasterless peer-to-peer ring
ConsistencyStrong (ACID)Tunable per query (ONE, QUORUM, ALL…)
JoinsYesNo
Default port33069042 (CQL)

2. Architecture

MySQL replication versus a Cassandra ringMySQL: one source server accepts writes and copies them to read replicas. Cassandra: six equal nodes in a ring; any node can accept a write, and each row is stored on several nodes chosen by its partition key.MySQL: source + replicasSourcereads + writesReplica 1readsReplica 2readsReplica 3readsWrites go to one serverCassandra: masterless ringN1N2N3N4N5N6every node equalrow copieson N1–N3Any node accepts reads and writes
Figure 1: MySQL sends writes to one source server; Cassandra spreads data (with replication factor 3 here) around a ring of equal nodes.
  • MySQL writes go to one source server (or one primary in Group Replication). Replicas copy the changes and serve reads. If the source fails, a replica is promoted.
  • Cassandra has no leader. A row's partition key is hashed to decide which nodes store it; the replication factor says how many copies. Any node can coordinate a request, so there is no single point of failure.
  • Cassandra writes go to a commit log and an in-memory table, later flushed to immutable SSTable files (an LSM-tree design), which makes writes very fast.

3. Data Modelling: Normalise vs Model per Query

In MySQL you design tables around the data and normalise it, then write any query you like. In Cassandra you design one table per query, choosing the partition key so each query reads a single partition. Data is often duplicated across tables on purpose.

Example: show the latest temperature readings for a sensor. MySQL:

mysql-readings.sql
CREATE DATABASE iot;
USE iot;
CREATE TABLE readings (
  sensor_id  VARCHAR(10),
  read_at    DATETIME,
  temp_c     DECIMAL(4,1),
  PRIMARY KEY (sensor_id, read_at)
);
INSERT INTO readings VALUES
('S-101','2026-03-01 10:00:00',21.4),('S-101','2026-03-01 10:05:00',21.9),
('S-101','2026-03-01 10:10:00',22.6),('S-202','2026-03-01 10:00:00',18.2),
('S-202','2026-03-01 10:05:00',18.0);

SELECT read_at, temp_c
FROM readings
WHERE sensor_id = 'S-101'
ORDER BY read_at DESC
LIMIT 2;

Result: 2 rows

read_attemp_c
2026-03-01 10:10:0022.6
2026-03-01 10:05:0021.9

Cassandra (CQL), designed for exactly that query: sensor_id is the partition key and read_at is a clustering column stored newest first:

cassandra.cql
CREATE TABLE readings_by_sensor (
  sensor_id text,
  read_at   timestamp,
  temp_c    decimal,
  PRIMARY KEY ((sensor_id), read_at)
) WITH CLUSTERING ORDER BY (read_at DESC);

SELECT read_at, temp_c FROM readings_by_sensor
WHERE sensor_id = 'S-101' LIMIT 2;

The CQL looks like SQL, but the rules are stricter. The ad-hoc query below is easy in MySQL. In Cassandra, filtering on the non-key column temp_c across all sensors needs a secondary index or ALLOW FILTERING (a full scan of every node), and joins are not available at all:

query.sql
SELECT sensor_id, MAX(temp_c) AS max_temp
FROM readings
WHERE temp_c > 20
GROUP BY sensor_id;

Result: 1 row

sensor_idmax_temp
S-10122.6

4. Consistency and Transactions

TopicMySQLCassandra
Multi-row transactionsYes, ACID across tablesNo general transactions; batches are atomic per partition
Read your own writeAlways (on the source)Depends on consistency level (e.g. QUORUM write + QUORUM read)
Conditional updatesNormal UPDATE … WHERELightweight transactions (IF NOT EXISTS), slower (Paxos)
Behaviour during network splitWrites stop if the source is unreachableKeeps accepting writes; replicas reconcile later

5. Performance Profile

  • Writes: Cassandra handles very high write rates spread over many nodes; MySQL is bounded by the source server.
  • Reads by key: both are fast. Cassandra reads one partition; MySQL uses its B-tree indexes.
  • Ad-hoc queries, joins, reports: MySQL is far better; Cassandra only answers the queries its tables were designed for.
  • Scaling: add a node to a Cassandra ring and data rebalances; growing MySQL writes usually means a bigger server or sharding.

6. When to Use Which

MySQLCassandra
Orders, payments, inventory, user accountsTime-series, sensor data, logs, event streams
Complex queries and reportingKnown, simple access patterns at huge scale
Strong consistency and transactionsAlways-on, multi-data-centre availability
Small to large data on one server or a clusterTerabytes to petabytes across many nodes
A common pattern: MySQL holds the business data, while Cassandra stores high-volume activity such as clicks or device readings.

7. Summary

  • MySQL is a relational, SQL, ACID database; Cassandra is a distributed wide-column database with CQL.
  • MySQL has a source server and replicas; Cassandra is a masterless ring where any node accepts writes.
  • Model MySQL tables around data (normalise); model Cassandra tables around queries (denormalise).
  • Cassandra trades joins and transactions for massive write scale and availability with tunable consistency.