🗄️ Databázová architektura
Klasifikace databází
Relační (SQL)
| DB |
Licence |
Use case |
| PostgreSQL |
Open source |
Univerzální, geospatial, analytika |
| MySQL |
Open source |
Web, LAMP stack |
| MariaDB |
Open source |
MySQL kompatibilní |
| Microsoft SQL Server |
Proprietary |
Enterprise .NET |
| Oracle DB |
Proprietary |
Enterprise |
| Amazon Aurora |
Managed |
MySQL/PostgreSQL kompatibilní |
NoSQL
| Typ |
DB |
Use case |
| Document |
MongoDB, Couchbase |
JSON data, flexibilní schema |
| Key-Value |
Redis, DynamoDB |
Cache, session store, real-time |
| Wide-column |
Cassandra, ScyllaDB |
Time-series, IoT, velká data |
| Graph |
Neo4j, Dgraph |
Vztahy, doporučení, social grafy |
Transaction isolation levels
| Úroveň |
Dirty Read |
Non-repeatable Read |
Phantom Read |
Serialization Anomaly |
| Read Uncommitted |
Ano (možné) |
Ano |
Ano |
Ano |
| Read Committed |
Ne (prevence) |
Ano |
Ano |
Ano |
| Repeatable Read |
Ne |
Ne |
Ano (PostgreSQL: Ne) |
Ano |
| Serializable |
Ne |
Ne |
Ne |
Ne |
Anomálie:
- Dirty Read — čtení dat z necommitnuté transakce (data mohou být rollbacknuta)
- Non-repeatable Read — stejný dotaz vrátí jiná data (jiná transakce mezitím updatovala řádek)
- Phantom Read — stejný dotaz vrátí nové řádky (jiná transakce insertla data splňující podmínku)
- Serialization Anomaly — výsledek transakcí není ekvivalentní žádnému sériovému pořadí
PostgreSQL specific
- Read Uncommitted se chová jako Read Committed (není implementováno)
- Repeatable Read v PG je Snapshot Isolation — zabraňuje i phantom reads
- Serializable v PG používá Serializable Snapshot Isolation (SSI) — detekce sériových konfliktů
PostgreSQL detail
MVCC (Multi-Version Concurrency Control)
- Každá transakce vidí snapshot dat (transaction snapshot) z okamžiku startu
- Staré verze řádků (tuple) zůstávají v tabulce, označené jako
xmax / xmin
- INSERT vytvoří nový tuple s
xmin = current_xid
- DELETE označí tuple
xmax = current_xid (nezmizí hned)
- UPDATE = DELETE old + INSERT new
- VACUUM fyzicky maže tuple starší než nejstarší aktivní snapshot
VACUUM a autovacuum
| Parametr |
Popis |
Výchozí |
autovacuum_vacuum_threshold |
Min. mrtvých řádků pro spuštění |
50 |
autovacuum_vacuum_scale_factor |
% z tabulky jako threshold |
0.2 (20 %) |
autovacuum_analyze_threshold |
Min. změněných řádků pro ANALYZE |
50 |
autovacuum_vacuum_cost_limit |
Limituje I/O vacuum (prevence zátěže) |
200 |
autovacuum_naptime |
Interval mezi kontrolami |
1 min |
deadlock_timeout |
Detekce deadlocků |
1 s |
Příznaky nedostatečného vacuum:
- Růst tabulky (bloat) — staré tuple zabírají místo
- Zhoršení výkonu index scanů (VISIBLE MAP není aktuální)
- XID wraparound hazard — emergency vacuum (může zastavit DB)
WAL archiving a PITR
- WAL (Write-Ahead Log) — append-only log všech změn
- WAL archiving — kontinuální záloha WAL segmentů (16 MB)
- PITR (Point-In-Time Recovery) — obnova k libovolnému okamžiku
- Restore base backup (pg_basebackup)
- Replay WAL archivů až k cílovému času
recovery_target_time = '2026-06-03 10:30:00 UTC'
Replication slots
- Physical replication slot — zaručuje, že WAL není smazán masterem, dokud ho replica nespotřebuje
- Logical replication slot — pro logickou replikaci (selectivní tabulky, transformace dat)
- Riziko: pokud replica spadne a slot není aktivní, WAL naroste na disku (disk full)
- Monitoring:
pg_replication_slots, pg_stat_replication
Replikace
| Typ |
Popis |
Latence |
| Synchronní |
Zápis potvrzen až po replikaci na všechny nod |
Vysoká, ale konzistentní |
| Asynchronní |
Zápis potvrzen ihned, replikace na pozadí |
Nízká, možný data loss |
| Semi-synchronní |
Potvrzení od majority nodů |
Kompromis |
Topologie
- Leader-Follower (Master-Slave) — čtení z replic
- Leader-Leader (Multi-master) — zápis na více nodů
- Quorum-based — R + W > N (Cassandra, DynamoDB)
Index types
| Typ |
Algoritmus |
Use case |
Operace |
Poznámka |
| B-tree |
Balanced tree |
Většina dotazů — =, <, >, BETWEEN, IN, LIKE (prefix) |
Rychlé vyhledávání, řazení |
Výchozí v PostgreSQL, MySQL |
| Hash |
Hash table |
Pouze = (equality) |
Rychlé lookup |
Malá velikost, nelze range dotazy |
| GiST |
Generalized Search Tree |
Full-text, geometrie, intervaly, IP rozsahy |
Rychlé: overlaps, contains, distance |
GIST pro geometrii (PostGIS), full-text |
| GIN (Generalized Inverted Index) |
Inverted index |
Pole, JSONB, full-text search |
contains (@>), overlaps (&&) |
Pomalý build, rychlé čtení |
| BRIN (Block Range Index) |
Min/Max per block range |
Velké tabulky, data v pořadí (time-series) |
Range dotazy na korelovaná data |
Extrémně malý (tisíckrát menší než B-tree) |
| SP-GiST |
Space-partitioned GiST |
Quad-tree, KD-tree, radix tree |
Partitioned search |
Geografické clustery, síťová data |
Index selection guide
| Query pattern |
Doporučený index |
Příklad |
WHERE user_id = 123 |
B-tree na user_id |
Uživatelský lookup |
WHERE status = 'active' AND created_at > '2026-01-01' |
Composite B-tree na (status, created_at) |
Filtrace + range |
WHERE data @> '{"key": "value"}' |
GIN na JSONB sloupec |
JSONB dotazy |
WHERE tags && ARRAY['urgent'] |
GIN na pole |
Tagy |
WHERE position <@> POINT(50, 14) < 1000 |
GiST na geometry |
Lokalitní dotazy |
WHERE event_time BETWEEN '2026-06-01' AND '2026-06-02' |
BRIN na event_time |
Time-series, logy |
WHERE email = 'user@example.com' |
Hash na email |
Equality only |
Query execution
Seq scan vs Index scan vs Bitmap scan
| Typ |
Popis |
Kdy se používá |
| Seq Scan |
Prochází všechny řádky tabulky |
Velká část tabulky (>10 %), malá tabulka, žádný vhodný index |
| Index Scan |
Hledá v indexu, pak náhodný přístup k heap |
Malá podmnožina dat (<5 %), selektivní dotazy |
| Index Only Scan |
Načítá data pouze z indexu (ne z heap) |
Všechny potřebné sloupce jsou v indexu (covering index) |
| Bitmap Scan |
Kombinace více indexů → bitmapa → heap access |
AND/OR podmínky na více indexovaných sloupcích |
| Bitmap Heap Scan |
Načítá řádky z bitmapy (srovnané) |
AND/OR kombinace, ~5-20 % tabulky |
EXPLAIN ANALYZE
Klíčové metriky: Execution Time, Planning Time, Buffers (hit/read/dirtied), Rows Removed by Filter, Actual Time (first...last)
Sharding
Distribuce dat napříč uzly podle shard klíče.
Hash-based sharding
Range-based sharding
- Data rozdělena podle rozsahu hodnot (např. uživatelé A-M, N-Z)
- Může vést k nerovnoměrnému rozdělení (hot spots)
Consistent hashing
- Minimalizuje přeuspořádání přidáním/odebráním nodu (pouze sousední shard)
- Virtual nodes (vnodes) — každý fyzický nod má více virtuálních bodů na ring (lepší distribuce)
- Koordinační služba: Cassandra (vnodes), Riak (vnodes), DynamoDB (Consistent Hashing)
Rebalancing
- Ruční — zastavit zápisy, přerozdělit data, restartovat
- Automatické — incremental migration (Cassandra vnodes)
- Proxy-based — Vitess (shard splitting), Citus (shard rebalancing)
Routing approaches
- Proxy-based — aplikace jde na proxy, ta routuje (Vitess, ProxySQL)
- Client-side — aplikace ví, na který shard jít
- DNS-based — každý shard má vlastní endpoint
CAP teorém
V distribuovaném systému lze mít pouze 2 ze 3:
- Consistency — všichni vidí stejná data
- Availability — každý request dostane odpověď
- Partition tolerance — systém funguje i přes výpadek komunikace
V praxi: P je vždy vyžadováno, volíme mezi CP (konzistence) a AP (dostupnost).
PACELC rozšíření
PACELC rozšiřuje CAP o chování za normálních podmínek (bez partition):
- Partition → Availability vs Consistency
- Else (bez partition) → Latency vs Consistency
| DB |
Partition volba |
Else volba |
| Cassandra |
AP (dostupnost) |
LC (nízká latence, eventual consistency) |
| DynamoDB (default) |
AP |
LC |
| MongoDB |
CP (primární) |
LC |
| PostgreSQL (single) |
CP |
CC |
| CockroachDB |
CP |
CC |
Quorum detail
- R (read quorum) + W (write quorum) > N (replication factor)
- Typické: N=3, R=2, W=2 (toleruje 1 node down)
- Sloppy quorum — při nedostupnosti nodu, data dočasně uložena na jiném nodu (nastolit konzistenci po obnově)
- Hinted handoff — dočasný zápis na jiný node s hintem, při obnově se data přenesou
Caching
| Vrstva |
Nástroj |
Use case |
| Application cache |
Redis, Memcached |
Session, API response cache |
| Database cache |
Built-in |
Query cache, buffer pool |
| CDN cache |
CloudFront, Fastly |
Static assets, API responses |
| HTTP cache |
Varnish, nginx |
Reverse proxy cache, ESI |
Cache strategie
| Strategie |
Popis |
Use case |
| Cache-aside |
Aplikace načte z cache, při miss jde do DB a naplní cache |
Obecná |
| Read-through |
Cache sama načte z DB při miss |
Jednoduché lookupy |
| Write-through |
Zápis jde do cache i DB zároveň |
Konzistence |
| Write-behind |
Zápis do cache okamžitě, do DB asynchronně |
Propustnost |
| Cache-aside (lazy loading) |
TTL + invalidace |
Nejčastější |
Redis detail
Data structures:
| Struktura |
Popis |
Use case |
| String |
Binární string (max 512 MB) |
Cache hodnoty, session tokeny, counters |
| Hash |
Map field-value |
Uživatelský profil, objekt v cache |
| List |
Linked list (push/pop na oba konce) |
Queue (RPUSH/LPOP), log stream |
| Set |
Unikátní hodnoty (unordered) |
Tags, deduplikace, memberships |
| Sorted Set |
Unikátní + score (řazení) |
Leaderboardy, rate limiting, timeouts |
| Bitmap |
Bitové pole |
Feature flagy, daily active users |
| HyperLogLog |
Approximate cardinality (12 KB = 2^64) |
Unikátní návštěvníci (error < 1%) |
| Stream |
Append-only log (Kafka-like) |
Event store, messaging |
Eviction policies:
| Policy |
Popis |
Use case |
| noeviction |
Chyba při zápisu když je plno |
Transakční data, neztrácet |
| allkeys-lru |
LRU na všechny klíče |
Obecná cache, standard |
| allkeys-lfu |
LFU na všechny klíče |
Často přistupovaná data |
| volatile-lru |
LRU na klíče s TTL |
Cache s expirací |
| volatile-ttl |
Nejblíž k expiraci |
Krátkodobá data |
| allkeys-random |
Náhodný |
Testování |
Redis Cluster vs Sentinel:
| Vlastnost |
Redis Sentinel |
Redis Cluster |
| Škálování |
Read replicas (master + replica) |
Data sharding (16384 hash slotů) |
| Auto-failover |
Ano (Sentinel) |
Ano (gossip-based) |
| Multi-key ops |
Ano (transactiony na masteru) |
Omezené (stejný hash slot) |
| Client komunikace |
Přes Sentinel (deprecated) |
Cluster nodes redirect (MOVED/ASK) |
| Minimální uzly |
Master + Replica + 3 Sentinel |
3 masters (každý s replikou) |
| Use case |
Vysoká dostupnost, single shard |
Multi-shard, horizontální škálování |
Connection pooling
| Pooler |
DB |
Typ |
Protokol |
| PgBouncer |
PostgreSQL |
Proxy (transaction/session) |
PostgreSQL wire |
| RDS Proxy |
PostgreSQL, MySQL |
Managed proxy |
AWS |
| ProxySQL |
MySQL |
Proxy (advanced routing) |
MySQL wire |
| Odyssey |
PostgreSQL |
Proxy (multithreaded) |
PostgreSQL wire |
| pgpool-II |
PostgreSQL |
Proxy (replication, load balancing) |
PostgreSQL wire |
PgBouncer režimy:
- Session pooling — spojení drženo po celou dobu session (aplikace) → overhead
- Transaction pooling — spojení vráceno po dokončení transakce → efektivnější (vyžaduje bezstavovost)
Migrace dat
Schéma migrace (PostgreSQL / MySQL)
Zero-downtime migrace
- Expand — přidání nového sloupce/tabulky (aplikace toleruje oba stavy)
- Migrate — backfill dat, update aplikace na nové schema
- Contract — odstranění starého sloupce/tabulky
Nástroje detail
| Nástroj |
Jazyk |
Strategie |
Zero-downtime |
Rollback |
| Flyway |
Java (multi-lang CLI) |
Versioned SQL |
Omezeně (jen additive) |
undo (limited, enterprise) |
| Liquibase |
Java (multi-lang CLI) |
Changesets (XML/YAML/JSON/SQL) |
Ano (changeset design) |
rollback <count> |
| Alembic |
Python |
Auto-generation, versioned |
Ano (branching) |
downgrade |
| Prisma Migrate |
TypeScript |
Declarative schema → diff |
Ano (shadow DB) |
migrate diff |
| gh-ost |
Go |
Triggerless online DDL (MySQL) |
Ano (binlog stream) |
Ne (progresivní) |
| pgroll |
Go |
Online schema migrace (PG) |
Ano (views, multiple versions) |
Ano (okamžitý) |
Data consistency patterns
| Pattern |
Popis |
Příklad |
| Strong consistency |
Po zápisu každý read vidí nejnovější data |
Single DB, Raft, Spanner |
| Eventual consistency |
Po zápisu se data časem propagují |
DNS, DynamoDB (default), Cassandra |
| Read-after-write |
Autor svůj zápis vždy vidí (ostatní eventual) |
Sociální sítě, komentáře |
| Causal consistency |
Kauzálně závislé operace viděny ve správném pořadí |
COPS, Orbe, MongoDB (causal clusters) |
| Monotonic reads |
Nevidíte starší data po tom, co jste viděli novější |
Cassandra (MONOTONIC_READ consistency) |
| Monotonic writes |
Zápisy od jednoho clienta v pořadí |
Queue-based, single leader |
Storage engines — přehled
B-Tree vs LSM-Tree
| Vlastnost |
B-Tree |
LSM-Tree |
| Zápis |
In-place update (náhodný I/O) |
Append-only (sekvenční I/O) |
| Čtení |
Rychlé (přímo v page) |
Pomalejší (merge z více SSTable) |
| Kompaktnost |
Horší (page fragmentation) |
Lepší (kompaktní SSTable) |
| Write amplification |
Nižší |
Vyšší (kompakce) |
| Read amplification |
Nižší |
Vyšší (bloom filtry pomáhají) |
| Typické DB |
PostgreSQL, MySQL (InnoDB) |
Cassandra, RocksDB, LevelDB |
Write-Ahead Log (WAL)
- Append-only log pro crash recovery
- Každá změna se zapíše do WAL před aplikací na data page
- Checkpoint = bod, od kterého je WAL při recovery potřeba
MVCC (Multi-Version Concurrency Control)
- Každá transakce vidí snapshot dat v okamžiku startu
- Staré verze řádků zůstávají v tabulce (vacuum/GC)
- Izolační úrovně: Read Committed, Repeatable Read, Serializable
Best practices
- Connection pooling — PgBouncer, RDS Proxy, ProxySQL
- Indexování podle query patternů — nemít zbytečné indexy
- Read replicas pro reporting a analytiku
- Backup & recovery — point-in-time recovery (PITR), pravidelné testy
- Query monitoring — slow query log, pg_stat_statements, performance_schema
- Encryption at rest & in transit
- Migrace v CI/CD — součást pipeline, ne manuálně
Zdroje
Odkazy, knihy a standardy: sources/databases/sources.md