Databases & Backend — Σχεδιασμός, Query, Reliability & Scale
Production data systems: data modeling, schema design, online migrations, indexing και query tuning, transactions και concurrency, replication/HA, partitioning/sharding, caching, full-text & vector search, observability, backup/restore και security.
Περιεχόμενα
Bonus 2026: 20) Recipes · 21) Playbook · 22) Capacity · 23) Glossary · 25) Decision tree · 26) Health-check · 27) Further reading
1) Data modeling που σώζει projects
Το DB schema είναι contract. Ξεκίνα από domain events και access patterns, όχι από τέλειο ER. Το καλό model απαντά σε “ποια queries θα είναι hot και πόσο stale ανέχομαι;”.
OLTP tables
Writes-first, normalized enough, constraints, FKs, integrity.
Read-optimized
Materialized views, caching, CQRS όπου χρειάζεται.
Events/Audit
Ιστορικό, reproducibility, concurrency boundaries.
Analytics
Columnar/warehouse, loose constraints, partitioned time series.
Rule of thumb: Μην “κακοποιείς” το κύριο schema για reporting. Χρησιμοποίησε ETL/materialized views/streams instead.
2) Schema & migrations
Schema changes σε συστήματα με traffic θέλουν μικρά, reversible, backward-compatible βήματα. Τα “big bang” migrations σε high-traffic services σχεδόν πάντα καταλήγουν σε downtime ή κλειδώματα.
CREATE TABLE events ( id bigint generated always as identity primary key, user_id uuid not null, type text not null, created_at timestamptz not null default now(), payload jsonb not null ); CREATE INDEX idx_events_user_created ON events(user_id, created_at desc);
Migrations: μικρές, reversible, backward-compatible. Ποτέ big-bang σε high-traffic services.
Rule of thumb: μην τρέχεις βαριά DDL σε ώρα αιχμής. Χρησιμοποίησε CREATE INDEX CONCURRENTLY και online εργαλεία (pg-online-schema-change, Reshape).
3) Indexing fundamentals
Τα indexes είναι “read accelerators” με write cost. Η μετρική επιτυχίας δεν είναι “πόσα indexes έχουμε” αλλά “πόσο καλυμμένα είναι τα hot paths”. Σχεδίασε indexes από τα query patterns (filters, sort, joins), όχι από τις στήλες μεμονωμένα.
- Χρησιμοποίησε
EXPLAIN (ANALYZE, BUFFERS)για πραγματικό κόστος, όχι εκτίμηση. - Indexes για equality + range scans (η σειρά στηλών στο composite παίζει ρόλο).
- Απόφυγε N+1 με joins/CTEs/batch fetch (DataLoader).
- Partial & covering indexes για μεγάλα hot subsets.
- Απόφυγε
SELECT *σε hot paths. - BRIN για τεράστια append-only time-series, GIN για jsonb/FTS, HNSW για vectors.
CREATE INDEX idx_orders_user_status_created ON orders(user_id, status, created_at DESC) INCLUDE (total);
2026 update: σε Postgres 17/18 δες EXPLAIN (MEMORY, SERIALIZE), parallel vacuum και βελτιωμένο logical replication.
4) Query tuning & plans
Το plan είναι η αλήθεια, όχι το SQL. Ένα λάθος join order ή ένα missing index μετατρέπει ένα 5ms query σε 5s. Μέτρα πάντα με EXPLAIN (ANALYZE, BUFFERS) σε δεδομένα σαν παραγωγής.
-- Hot path: index scan αντί για seq scan SELECT id, total, created_at FROM orders WHERE user_id = $1 AND status = $2 ORDER BY created_at DESC LIMIT 20;
- Keyset pagination με
(created_at, id)αντί γιαOFFSET. - Index-only scans όταν όλες οι στήλες είναι στο index.
- Materialized views για βαριά aggregates (refresh ανά 5').
5) Transactions & consistency
Επίλεξε συνειδητά μεταξύ strong consistency και eventual consistency. Μικρές transactions, σαφή boundaries και idempotency για ασφαλή retries.
BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = $1; INSERT INTO transfers (from_id, to_id, amount) VALUES ($1,$2,100); COMMIT;
| Isolation level | Προστασία | Risk | Πότε χρησιμοποιείται |
|---|---|---|---|
| Read Committed | Χωρίς dirty reads | Non-repeatable reads | Default (Postgres) |
| Repeatable Read | Σταθερό snapshot | Phantoms (σπάνια) | Reporting/analytics |
| Serializable | Πλήρης | Υψηλό retry contention | Critical financial ops |
Σημείωση 2026: το Postgres δεν υλοποιεί πραγματικό Read Uncommitted (συμπεριφέρεται σαν Read Committed). Για analytics προτίμησε Repeatable Read + export snapshot.
- Μικρό scope + μικρή διάρκεια transaction.
- Idempotency keys για ασφαλή retries.
- Outbox pattern για αξιόπιστα events (CDC με Debezium/Redpanda).
- Retry με exponential backoff + jitter.
6) Isolation levels στην πράξη
Κανόνας: ξεκίνα από Read Committed. Ανέβασε επίπεδο μόνο με μετρήσιμο anomaly (π.χ. phantom σε report) και πάντα με retry logic για serialization failures (40001).
BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT sum(total) FROM orders WHERE created_at >= now() - interval '30 days'; COMMIT;
7) Locks, contention & deadlocks
Το πρόβλημα σπάνια είναι “έχω locking”, αλλά “ποιο lock περιμένει ποιο”. Τα deadlocks είναι συμπτώματα λάθος σειράς κλειδώματος.
- Σταθερή σειρά απόκτησης locks (π.χ. ταξινόμηση by id).
- Μικρές transactions για μικρότερο lock duration.
SKIP LOCKEDγια queue-like workloads.- Γρήγορη καταγραφή deadlock logs με transaction ids.
- Retry logic όταν ανιχνευθεί deadlock (
40P01).
-- url-safe lock pattern (Postgres) SELECT * FROM orders WHERE id = $1 FOR UPDATE SKIP LOCKED;
8) Replication & HA
Τα read replicas κλιμακώνουν τα reads, αλλά εισάγουν stale reads. Σχεδίασε κάθε path ανάλογα με την ανοχή σε παλιά δεδομένα (π.χ. το balance πάντα από primary).
Async replication
Απλό, αλλά με παράθυρο απώλειας δεδομένων σε failover.
Sync replication
Χωρίς απώλεια δεδομένων, αλλά με κόστος latency.
Failover automation
Patroni / Cloud HA με γρήγορο promotion. Το 2026: Neon autoscaling + Supabase HA + AlloyDB.
Read routing
Consistency-aware routes.
Trade-off: το HA δεν σημαίνει zero trade-offs. Επίλεξε ανοχή σε stale reads για κάθε flow ξεχωριστά.
9) Partitioning & sharding
Το partitioning είναι συνήθως time-based (ανά μήνα/εβδομάδα) για retention και γρήγορο vacuum. Το sharding είναι πολύπλοκο και θέλει δική του αρχιτεκτονική.
CREATE TABLE metrics (
ts timestamptz not null,
metric text not null,
value double precision not null
) PARTITION BY RANGE (ts);
CREATE TABLE metrics_2026_10 PARTITION OF metrics
FOR VALUES FROM ('2026-10-01') TO ('2026-11-01');
- Retention: drop old partitions (instant, cheap).
- Maintenance windows με partition detach (zero-downtime archival).
- Shard-key awareness για join-heavy workloads.
10) Redis & caching πέρα από τα basics
Redis patterns: cache-aside, write-through, TTL jitter, locks, rate limiting, queues. Το πραγματικό κόστος είναι το invalidation — σχεδίασέ το από την αρχή.
- Cache-aside: απλό read path, εσύ γεμίζεις το cache.
- Write-through: ισχυρό read-after-write consistency.
- TTL jitter: αποφυγή stampede (thundering herd).
- Locks: SET NX με timeout και ownership token.
- Rate limiting: sliding window / token bucket.
- Queues/streams: async processing και fan-out.
-- redis (pseudocode)
SET user:123:profile "{...}" EX 300 NX
2026 update: Redis 8 vs Valkey 8 / Dragonfly / Upstash. Για νέα projects δες Valkey (open-source fork) ή serverless Redis (Upstash). Για queues/streams σε κλίμακα: NATS JetStream, Redpanda/Kafka + outbox, όχι Redis lists χωρίς ACK.
11) Full-text & vector search
FTS με tsvector, ranking και highlighting για keyword αναζήτηση. Vectors για σημασιολογική (embeddings). Συχνά το “hybrid search” (BM25 + vector με RRF rerank) κερδίζει σε ποιότητα.
ALTER TABLE docs ADD COLUMN tsv tsvector GENERATED ALWAYS AS
to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,'')) STORED;
CREATE INDEX idx_docs_tsv ON docs USING gin (tsv);
- FTS: πολύ καλό για exact/keyword αναζητήσεις.
- Vector: καλό rerank αλλά θέλει evals (recall@k, latency).
- Hybrid: union/rerank (RRF) πολλές φορές νικά.
2026 update: pgvector 0.8+ με HNSW (m, ef_construction tuning), quantization, και hybrid με ts_rank + vector distance. Για μεγάλη κλίμακα: Qdrant / Weaviate / Typesense. Δες και το Vector DB in Production.
12) Online migrations (expand & contract)
Μοτίβο για zero downtime: πρόσθεσε → γέμισε → συσχέτισε → καθάρισε. Μία φάση ανά deploy, με μετρήσιμα checks.
| Phase | Ενέργεια | Ρίσκο |
|---|---|---|
| Expand | Νέο column/table/index | Low |
| Backfill | Μικρά batches, checksums | Medium |
| Switch | Read/write path update | Medium/High |
| Contract | Drop legacy objects | Medium (validate usage) |
13) Observability για DB/backends
Metrics
QPS, p95/p99, active connections, replication lag.
Logs
Structured with tx id, slow query logs.
Traces
Endpoint → DB spans με duration sampling (OpenTelemetry).
Alerts
SLO-based, όχι στατικά thresholds σε θορυβώδεις μετρικές.
14) Backup/restore & DR
- Όρισε RPO/RTO ανά dataset (όχι ένα νούμερο για όλα).
- Logical backups + physical (PITR) για μεγάλες βάσεις.
- Test restore κάθε μήνα (πραγματικό drill, με χρονόμετρο).
- Cross-region copies με ξεχωριστά encryption keys (KMS).
- Runbook για partial restore και point-in-time recovery.
Backup χωρίς test restore δεν είναι backup. Το 2026: pgBackRest + WAL-G/S3, immutability (object lock) κατά ransomware.
15) Security για databases
CREATE POLICY user_rows ON orders
FOR SELECT USING (user_id = current_setting('app.user_id')::uuid);
- Least privilege users/roles (ξεχωριστό role για migrations, app, readonly).
- mTLS/TLS + IP allowlists + private subnets.
- Parameterized queries αντί για dynamic SQL (αποτροπή injection).
- RLS για multi-tenant (με
current_setting('app.user_id')). - Secret management με rotation (Vault / cloud secret manager, όχι hardcoded creds).
16) Anti-patterns
- Πρόωρη normalization/denormalization χωρίς query context.
- Indexes χωρίς monitoring → write penalty και φουσκωμένο vacuum.
- Μεγάλες transactions → locks/timeouts.
- Cache inconsistency από λάθος invalidation.
- Χωρίς idempotency σε retries (διπλοχρεώσεις).
- ORM N+1 σε list endpoints χωρίς batching.
17) Case study: από slow query σε 50x καλύτερο p95
Παράδειγμα: report query που έκανε sequential scan και nested loops σε joins. Μετά από tuning:
- Σωστό composite index για WHERE (user_id, status, created_at).
- Covering index (INCLUDE total) → index-only scan.
- Batch fetch με cursor για μεγάλες σελίδες.
- Materialized view για reporting (refresh κάθε 5 min).
- Δεδομένη παρακολούθηση p95/p99 και cache hit rate.
Αποτέλεσμα (ενδεικτικό): p95 1.8s → 35ms, cache hit 92%, DB CPU −45%. Πάντα μετράς πριν/μετά με ίδιο φορτίο.
18) Production checklist
- Indexes για κάθε hot query + μέτρηση unused indexes.
- Plan επαληθευμένο με ANALYZE, BUFFERS.
- Backups/PITR δοκιμασμένα (restore drill).
- Replication lag & failover drill (< 1s p99 lag στόχος).
- Secrets rotation & RBAC / RLS.
- Connection pooling (PgBouncer / Supavisor / Neon pooler) — μέγεθος pool μετρημένο.
- Monitoring/alerts και SLOs ορισμένα (p95, error budget).
- Load test + soak test πριν το production + rollback plan.
20) Query tuning recipes
Πρακτικές συνταγές για hot reads: διάλεξε με βάση το latency (p95/p99), όχι τη θεωρητική πολυπλοκότητα.
| Συνταγή | Πότε τη χρησιμοποιείς | Παγίδα |
|---|---|---|
| SELECT ... WHERE + index scan | Equality/range με συγκεκριμένα filters | Λάθος index order → seq scan |
| Index-only scan | Hot read όπου όλα είναι στο index | Heap vacuum (visibility map) να είναι καθυστερημένο |
| Materialized view | Aggregates που αλλάζουν σπάνια | Refresh cost & stale data |
| Cursor pagination | Πολύ μεγάλα datasets, σταθερή σειρά | Χρειάζεται ντετερμινιστικό sort key |
-- Keyset pagination SELECT id, created_at, title FROM posts WHERE (created_at, id) < ($1, $2) ORDER BY created_at DESC, id DESC LIMIT 50;
Συμβουλή: μέτρα πάντα p95/p99, όχι μέσο όρο. Τα outlier requests γεμίζουν τις ουρές.
21) Migration playbook: online migrations
Σε μεγάλα συστήματα, μια αλλαγή σχήματος είναι deployment pipeline, όχι SQL script.
| Στάδιο | Στόχος | Πρακτικό tip |
|---|---|---|
| 0. Observe | Base metric σημερινό query profile | Αποθήκευσε p95 μέσα, δεν προχωράς με “φαίνεται καλά” |
| 1. Expand | Νέο schema + indexes | Δημιούργησε “dark launch” paths χωρίς switch |
| 2. Backfill | Συμπλήρωση δεδομένων | Idempotent batches, checkpoint και throttle |
| 3. Dual write | Γράψε και στα δύο schema | Feature flags + shadow verification |
| 4. Switch read | Νέο path ως source of truth | Canary traffic + alerts |
| 5. Contract | Drop legacy | Αφού κανείς δεν διαβάζει (verify usage) |
Rule: μία αλλαγή = 1 phase ανά deploy. Ποτέ “βαριά” deploy με πολλές φάσεις μαζί.
22) Use cases & capacity planning
Το schema χωρίς traffic context είναι όνειρο. Χτίσε μοντέλο με:
Profiles
- DAU, sessions/day, peak RPS.
- Hot queries per user session.
- Retention window ημέρες/μηνών.
Capacity
- Writes/s και IOPS headroom.
- Storage growth (GiB/ημέρα) και retention.
- Replica lag budgets.
Reliability
- RPO, RTO, failover time.
- Alerts με SLOs, όχι θόρυβος.
- Access restrictions & isolation.
Quality gates
- Checklist με metric promotion.
- Rollback window & feature flags.
- Post-mortem αν threshold violated.
23) Mini glossary
| Όρος | Ορισμός |
|---|---|
| WAL | Write-ahead log που κρατάει αλλαγές πριν εφαρμοστούν. |
| Vacuum | Καθαρισμός dead tuples. |
| Replication lag | Καθυστέρηση αντιγραφής μεταξύ primary/replica. |
| MVCC | Multi-version concurrency control. |
| Shard key | Κλειδί διαχωρισμού horizontal splits. |
| IOPS | Ops/δευτ. που αντέχει αποθήκευση. |
| SLO | Service level objective. |
24) Further reading map
- Vector DB in Production — latency HNSW, hybrid search.
- RAG από το μηδέν — pgvector setup και ingestion pipeline.
- Personal Knowledge Base με AI — embedding store, recall metrics.
- VLA models — data pipeline patterns και storage.
- K3s Homelab — schema-ready practice.
25) Decision tree για τεχνολογίες
| Ανάγκη | Λύση πρώτης επιλογής | Αποφυγή |
|---|---|---|
| Σχεσιακά δεδομένα, transactions | Postgres / similar RDBMS | “Schema-less” χωρίς plan |
| Πολύ υψηλή κλίμακα reads | Redis cache + replicas | Αμφιβόλου Cache invalidation |
| Event audit trail | Event sourcing / outbox | Μόνο application logs |
| Full-text search | FTS index (tsvector) + hybrid | Manual LIKE everywhere |
| Semantic search | Vector embeddings + rerank | Naive embedding χωρίς evaluation |
| Analytics-heavy workload | Warehouse / columnar store (ClickHouse, DuckDB, BigQuery) | Production OLTP για reporting |
Σκέψου το “χαλινάρι”: τεχνολογία που επιτρέπει “ταχύτητα” χωρίς γνώση query patterns = technical debt.
26) 30-second DB health check
- p95/p99 queries (top 5) — slow query ratio < 1%
- Connection utilization vs pool max.
- Replication lag p99 < 1s.
- Cache hit rate για hot keys > 80%.
- Backup που τελείωσε τελευταίες 24h.
- Unused indexes (optimize writes).
- Long-running transactions > 30s count = 0.
- Vacuum/autovacuum health basic.
Αν οποιοδήποτε κριτήριο αποτύχει, έχεις το επόμενο προτεραιότητα.
thedarkmonster