Vergleich der Modelle
Eigenschaften
Strategien
CREATE KEYSPACE sensor_data
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 3,
'dc2': 2
};
Hot Partitions vermeiden
date als einziger Partition Key (alle Writes heute → ein Node)(sensor_id, date) → gleichmäßige VerteilungPRIMARY KEY (partition_key, clustering_key)CREATE TABLE messwerte (
sensor_id TEXT,
zeitpunkt TIMESTAMP,
temperatur DOUBLE,
PRIMARY KEY (sensor_id, zeitpunkt)
) WITH CLUSTERING ORDER BY
(zeitpunkt DESC);
Ergebnis
sensor_id | zeitpunkt | temperatur
-----------+---------------------+-----------
s-001 | 2024-06-01 12:00:00 | 23.4
s-001 | 2024-06-01 11:00:00 | 22.8
s-001 | 2024-06-01 10:00:00 | 22.1
Keyspace erstellen
CREATE KEYSPACE mein_ks
WITH replication = {
'class': 'SimpleStrategy',
'replication_factor': 3
};
Tabelle erstellen
CREATE TABLE mein_ks.benutzer (
benutzer_id UUID,
nachname TEXT,
vorname TEXT,
email TEXT,
erstellt TIMESTAMP,
PRIMARY KEY (benutzer_id)
);
Compound Primary Key
CREATE TABLE mein_ks.bestellungen (
kunden_id UUID,
bestell_ts TIMESTAMP,
produkt_id UUID,
menge INT,
preis DECIMAL,
PRIMARY KEY (kunden_id, bestell_ts)
) WITH CLUSTERING ORDER BY
(bestell_ts DESC);
Hinweise
Schreiben
INSERT INTO messwerte
(sensor_id, zeitpunkt, temperatur)
VALUES
('s-001', toTimestamp(now()), 23.5);
UPDATE messwerte
SET temperatur = 24.0
WHERE sensor_id = 's-001'
AND zeitpunkt = '2024-06-01 12:00:00';
DELETE FROM messwerte
WHERE sensor_id = 's-001'
AND zeitpunkt = '2024-06-01 10:00:00';
Lesen
-- Effizient: Partition Key angegeben
SELECT * FROM messwerte
WHERE sensor_id = 's-001';
-- Bereichsabfrage auf Clustering Key
SELECT * FROM messwerte
WHERE sensor_id = 's-001'
AND zeitpunkt > '2024-06-01 00:00:00';
-- Achtung: ALLOW FILTERING → Full Scan
SELECT * FROM messwerte
WHERE temperatur > 25.0
ALLOW FILTERING;
ALLOW FILTERING explizit erforderlichVirtuelle Nodes (Vnodes)
Inhalte
Strategien
Hinted Handoff
Konfigurierbar pro Anfrage (Tunable Consistency)
Starke Konsistenz durch Tuning
-- Konsistenzlevel in cqlsh setzen
CONSISTENCY QUORUM;
SELECT * FROM messwerte
WHERE sensor_id = 's-001';
Eigenschaften
Merge-Strategie
Strategien
gc_grace_seconds
gc_grace_seconds (Standard: 10 Tage) endgültig entferntProblem: zu viele Tombstones
-- TTL beim Schreiben setzen
INSERT INTO messwerte
(sensor_id, zeitpunkt, temperatur)
VALUES
('s-001', toTimestamp(now()), 23.5)
USING TTL 86400; -- 1 Tag in Sekunden
-- TTL pro Tabelle konfigurieren
CREATE TABLE logs (
id UUID,
ts TIMESTAMP,
msg TEXT,
PRIMARY KEY (id, ts)
) WITH default_time_to_live = 604800;
-- 7 Tage
Vorgehen
1. Anforderungen erfassen
→ Welche Abfragen werden gestellt?
→ Welche Filter? Welche Sortierung?
2. Zugriffsmuster auflisten
→ GET sensor by ID
→ GET latest readings for sensor
→ GET all sensors in region
3. Tabellen entwerfen
→ Partition Key aus Filterbedingung
→ Clustering Key aus Sortierung
Anti-Pattern:
SELECT * FROM sensoren
WHERE region = 'Berlin'
AND typ = 'Temperatur'
ORDER BY wert DESC
→ Mehrere Nicht-PK-Filter: ALLOW FILTERING
Lösung: eigene Tabelle für diesen Query
CREATE TABLE sensoren_by_region_typ (
region TEXT,
typ TEXT,
wert DOUBLE,
id UUID,
PRIMARY KEY ((region, typ), wert)
) WITH CLUSTERING ORDER BY (wert DESC);
Anforderung
Schema-Design
CREATE TABLE messwerte_stündlich (
sensor_id TEXT,
stunde TEXT, -- 'YYYY-MM-DD-HH'
zeitpunkt TIMESTAMP,
temperatur DOUBLE,
luftfeucht DOUBLE,
PRIMARY KEY ((sensor_id, stunde), zeitpunkt)
) WITH CLUSTERING ORDER BY
(zeitpunkt DESC)
AND default_time_to_live = 2592000;
-- 30 Tage TTL
Abfragen
-- Letzte Stunde eines Sensors
SELECT * FROM messwerte_stündlich
WHERE sensor_id = 's-001'
AND stunde = '2024-06-01-12';
-- Einfügen (Batch für Atomarität)
BEGIN BATCH
INSERT INTO messwerte_stündlich
(sensor_id, stunde, zeitpunkt,
temperatur, luftfeucht)
VALUES
('s-001', '2024-06-01-12',
'2024-06-01 12:05:00', 23.5, 61.2);
APPLY BATCH;
Partitionsgröße kontrollieren
(sensor_id, stunde) begrenzt Partition auf 3.600 Rows/hStärken Cassandra
Stärken Relationale DB
Schwächen Cassandra
Typische Einsatzgebiete
Cassandra in der Praxis
Managed Angebote