Ölçeklenebilir Veri Depolama: SQL ve NoSQL
Erişim örüntülerine, tutarlılığa ve ölçek gereksinimlerine göre ilişkisel veritabanları, anahtar-değer depoları, belge veritabanları ve geniş sütunlu depolar arasından seçim yapın.
Ölçeklenebilir Veri Depolama: SQL ve NoSQL, CoddyKit'te ücretsiz bir DSA Interview Prep dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DSA Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DSA Interview Prep kursu toplamda 4 dersten oluşur.
Depolama Seçimi Bir Ödünleşimdir
Bir veri deposu seçmek, sistem tasarımındaki en kritik kararlardan biridir. Her durumda en iyi olan bir veritabanı yoktur — her tür, farklı erişim kalıpları, tutarlılık garantileri ve ölçek özellikleri için optimize edilmiştir. Bu seçimi üretimde yanlış yapmak, aylar süren zahmetli geçiş çalışmalarına yol açar.
Mülakatlarda mülakatçılar, temel farklılıkları anlayıp anlamadığınızı ve bir depolama altyapısını bir problemin gereksinimleriyle eşleştirip eşleştiremediğinizi ölçer. Soru hiçbir zaman “hangisi daha iyi?” değil, “bu özel iş yükü için hangisi daha iyi?” şeklindedir. Seçiminizi her zaman belirli gereksinimlerle gerekçelendiriniz.
# Storage decision matrix summary
factors = [
'Data structure (tabular, documents, key-value, graph, time-series)',
'Read vs write ratio (read-heavy, write-heavy, balanced)',
'Query patterns (point lookups, range scans, aggregations, joins)',
'Consistency requirements (ACID vs eventual consistency)',
'Scale requirements (single node, sharding, global distribution)',
'Latency requirements (milliseconds vs microseconds)',
'Team familiarity and operational complexity',
]
print('Key factors for storage selection:')
for f in factors:
print(f' - {f}')İlişkisel Veritabanları (SQL): Güçlü Yönleri
İlişkisel veritabanları (PostgreSQL, MySQL, SQLite), verileri sabit şemalara sahip tablolarda saklar ve ACID işlemlerini — Atomiklik, Tutarlılık, Yalıtım, Kalıcılık — destekler. Birleştirmeler, toplulaştırmalar ve filtreler içeren karmaşık sorgularda özellikle başarılıdır; bu nedenle iyi tanımlanmış ilişkilere sahip yapılandırılmış veriler için idealdir.
Temel güçlü yönleri: SQL aracılığıyla çok tablolु karmaşık sorgular, veri bütünlüğü için dış anahtar kısıtlamaları, güçlü dizinleme (B-ağacı, karma, tam metin), çoğaltma ve yedeklemeyi içeren olgun bir ekosistem. Verileriniz yüksek düzeyde ilişkisel olduğunda, tutarlılık kritik önem taşıdığında ve sorgular karmaşık ve çeşitlilik gösterdiğinde SQL kullanınız.
# SQL excels at: complex queries, joins, transactions
# Example: find top 5 products by revenue this month
sql_query = '''
SELECT p.name, SUM(oi.quantity * oi.price) AS revenue
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE o.created_at >= DATE_TRUNC('month', NOW())
GROUP BY p.id, p.name
ORDER BY revenue DESC
LIMIT 5;
'''
print('SQL shines for relational queries with JOINs:')
print(sql_query)
print('ACID guarantees example (transfer $100 between accounts):')
transfer_sql = '''
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- either both succeed or neither does
'''
print(transfer_sql)SQL Ölçeklendirme Zorlukları
SQL veritabanları doğal olarak dikey ölçeklenir (daha büyük sunucu, daha fazla CPU/RAM), ancak yatay ölçekleme karmaşıktır. Okuma replikaları, okumaları replikalara ve yazmaları birincil düğüme yönlendirerek okuma ağırlıklı iş yüklerini karşılar. Ancak parçalama eklemediğiniz sürece yazma kapasitesi tek bir birincil düğümle sınırlıdır.
Parçalama, verileri bir parçalama anahtarına (ör. kullanıcı_kimliği mod N) göre birden fazla veritabanı örneğine dağıtır. Bu, yazma ölçeği sağlar; ancak SQL'in en güçlü özelliklerinden ikisi olan parçalar arası birleştirmeleri ve işlemleri kullanılamaz hâle getirir. Çoğu web uygulaması, yaklaşık 5-10 TB veriye veya saniyede yaklaşık 100 bin yazma işlemine ulaştığında tek düğümlü SQL'in kapasitesini aşar.
# SQL scaling strategies
strategies = {
'Read replicas': {
'how': 'One primary (writes), multiple replicas (reads)',
'scales': 'Read throughput (10x+)',
'limit': 'Write throughput still bounded by single primary',
},
'Connection pooling (PgBouncer)': {
'how': 'Pool of persistent DB connections shared among app servers',
'scales': 'Connection count (PostgreSQL max ~500 connections)',
'limit': 'Does not increase query throughput',
},
'Horizontal sharding': {
'how': 'Partition rows by shard key across N database instances',
'scales': 'Both reads and writes (N×)',
'limit': 'Cross-shard joins and transactions broken; complex routing',
},
'CQRS': {
'how': 'Separate write model (SQL) from read model (denormalised/NoSQL)',
'scales': 'Optimise each path independently',
'limit': 'Eventual consistency between write and read models',
},
}
for strategy, info in strategies.items():
print(f'{strategy}:\n How: {info["how"]}\n Scales: {info["scales"]}\n Limit: {info["limit"]}\n')Anahtar-Değer Depoları: Redis ve DynamoDB
Anahtar-değer depoları, verileri anahtar → değer çiftleri olarak saklar ve anahtar üzerinden O(1) okuma ve yazma sunar. Aşırı performans ve yatay ölçeklenebilirlik karşılığında sorgu esnekliğinden ödün verir. Bellek içi Redis mikrosaniye düzeyinde gecikme sağlar; yönetilen DynamoDB ise her türlü kapasiteye otomatik ölçeklenerek tek haneli milisaniye düzeyinde gecikme sağlar.
Anahtar-değer depolarını şunlar için kullanınız: oturum depolama, önbellekleme, özellik işaretleri, URL kısaltıcı eşlemeleri, alışveriş sepetleri ve gerçek zamanlı sıralama tabloları. Şu durumlarda kullanmayınız: karmaşık sorgulara, varlıklar arasındaki ilişkilere veya özel amaçlı filtrelemeye ihtiyaç duyduğunuzda — yalnızca tam anahtara göre arama yapabilirsiniz.
# Key-value store use cases
kv_operations = {
'GET key': 'O(1) point lookup — the core operation',
'SET key value': 'O(1) insert or update',
'DEL key': 'O(1) delete',
'EXPIRE key ttl': 'Set time-to-live; key auto-deleted after ttl seconds',
'INCR key': 'Atomic increment — useful for counters and rate limiting',
'LPUSH/LRANGE': 'List operations — useful for queues and recent-items feeds',
'ZADD/ZRANGE': 'Sorted set — leaderboards, rate limiting with sliding window',
}
print('Redis operation set:')
for op, desc in kv_operations.items():
print(f' {op:25s}: {desc}')
print('\nDynamoDB vs Redis:')
print(' Redis: microsecond latency, in-memory, needs persistence config')
print(' DynamoDB: single-digit ms, managed, auto-scaling, durable by default')Belge Depoları: MongoDB
Belge depoları (MongoDB, Couchbase), verileri JSON benzeri belgeler olarak saklar ve esnek şemalara izin verir — aynı koleksiyondaki belgelerin alanları birbirinden farklı olabilir. Herhangi bir alan üzerinde dizinlemeyi ve oldukça kapsamlı sorguları (filtreler, projeksiyonlar, toplulaştırmalar) destekler; ancak birden çok belgeyi kapsayan işlemler SQL'e kıyasla daha sınırlıdır.
Belge depoları şu uygulamalar için uygundur: verilerin varlığa göre farklı biçimlere sahip olması (farklı özelliklere sahip kullanıcı profilleri), şemanın hızla gelişmesinin beklenmesi (veri modellerini sık sık değiştiren yeni girişimler) veya okuma kalıplarının tablolar arasında birleştirme yapmak yerine varlıkların tamamını getirmeye dayanması.
# MongoDB document example
user_doc = {
'_id': 'user123',
'name': 'Alice',
'email': 'alice@example.com',
'preferences': {
'theme': 'dark',
'language': 'en',
'notifications': ['email', 'push']
},
'addresses': [
{'type': 'home', 'city': 'Berlin', 'country': 'DE'},
{'type': 'work', 'city': 'Munich', 'country': 'DE'}
],
'subscription_tier': 'pro',
# Note: not all users have all fields -- flexible schema!
}
import json
print('Document structure (flexible schema):')
print(json.dumps(user_doc, indent=2))
print('\nDocument store strengths:')
print(' - Nested/array fields without joins')
print(' - Flexible schema (different fields per document)')
print(' - Scales horizontally by sharding on _id')Geniş Sütunlu Depolar: Cassandra
Geniş sütunlu depolar (Apache Cassandra, HBase), verileri satır ve sütunlarda saklar; ancak her satırın farklı bir sütun kümesine sahip olmasına izin verir. Birçok düğüme dağıtılmış çok yüksek yazma kapasitesi için tasarlanmıştır ve varsayılan olarak nihai tutarlılık sunar. Cassandra, yazma kapasitesini doğrusal olarak ölçekler — düğüm sayısını iki katına çıkarmak yazma kapasitesini de iki katına çıkarır.
Ödünleşim şudur: sorgular, bölümleme anahtarı etrafında tasarlanmalıdır. Rastgele sütunlarda verimli biçimde filtreleme veya sıralama yapamazsınız — önce sorgu biçimini tanımlamalı, ardından tabloyu buna uyacak şekilde tasarlamalısınız. Bu, SQL'in “veriyi tasarla, ardından istediğin sorguyu yaz” yaklaşımının tam tersidir.
# Cassandra table design for time-series events
# Design around the query: 'give me all events for user X, most recent first'
cassandra_table = '''
CREATE TABLE user_events (
user_id UUID,
event_time TIMESTAMP,
event_type TEXT,
metadata MAP<TEXT, TEXT>,
PRIMARY KEY (user_id, event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);
-- Query (matches partition key exactly):
SELECT * FROM user_events WHERE user_id = ? LIMIT 100;
'''
print('Cassandra wide-column design:')
print(cassandra_table)
print('Properties:')
print(' - user_id = partition key (all rows for one user on same node)')
print(' - event_time = clustering key (sorted within partition)')
print(' - Very fast writes: append-only, no locking')
print(' - Cannot query by event_type alone (no partition key)')CAP Teoremi: Tutarlılık, Kullanılabilirlik, Bölünme Toleransı
CAP teoremi, dağıtık bir sistemin şu üç özellikten en fazla ikisini garanti edebileceğini belirtir: Consistency (her okumanın en son yazılan veriyi döndürmesi), Availability (her isteğin hatasız bir yanıt alması) ve Partition tolerance (ağ bölünmelerine rağmen sistemin çalışmaya devam etmesi).
Ağ bölünmeleri dağıtık sistemlerde her zaman meydana gelebildiğinden, gerçek seçim CP ile AP arasındadır: CP tutarlılığa öncelik verir ve bölünme sırasında istekleri reddedebilir; AP kullanılabilirliğe öncelik verir ve güncelliğini yitirmiş veriler döndürebilir. SQL veritabanları genellikle CP'dir; Cassandra ve DynamoDB ise AP'dir (varsayılan olarak nihai tutarlılık). Redis Cluster CP'dir.
# CAP theorem applied to common databases
databases = {
'PostgreSQL (single node)': {'C': True, 'A': True, 'P': False, 'note': 'Not distributed; CA'},
'PostgreSQL (multi-AZ)': {'C': True, 'A': False, 'P': True, 'note': 'CP: primary fails over, brief downtime'},
'MySQL Cluster': {'C': True, 'A': False, 'P': True, 'note': 'CP'},
'Cassandra': {'C': False, 'A': True, 'P': True, 'note': 'AP: eventual consistency default'},
'DynamoDB (default)': {'C': False, 'A': True, 'P': True, 'note': 'AP: eventual consistency'},
'DynamoDB (strong read)': {'C': True, 'A': False, 'P': True, 'note': 'CP: strongly consistent reads'},
'Redis Cluster': {'C': True, 'A': False, 'P': True, 'note': 'CP'},
'MongoDB (default)': {'C': True, 'A': False, 'P': True, 'note': 'CP: reads from primary'},
}
for db, caps in databases.items():
c_str = 'C' if caps['C'] else '-'
a_str = 'A' if caps['A'] else '-'
p_str = 'P' if caps['P'] else '-'
print(f'{db:35s} [{c_str}{a_str}{p_str}] {caps["note"]}')Depolama Seçimi: Karar Çerçevesi
Mülakatlarda depolama seçimi için pratik bir karar çerçevesi:
- ACID işlemlerine mi ihtiyacınız var? → İlişkisel veritabanı (PostgreSQL, MySQL)
- Milisaniyenin altında arama sürelerine veya önbellekleme özelliğine mi ihtiyacınız var? → Anahtar-değer deposu (Redis)
- Esnek şemaya veya belge odaklı verilere mi ihtiyacınız var? → Belge deposu (MongoDB)
- Zaman serisi ya da olay verileriyle saniyede 100 binden fazla yazma kapasitesine mi ihtiyacınız var? → Geniş sütunlu depo (Cassandra)
- Yönetilen ölçeklendirmeyle küresel dağıtıma mı ihtiyacınız var? → DynamoDB veya Cosmos DB
- Graf geçişlerine mi ihtiyacınız var? → Graf veritabanı (Neo4j)
# Decision tree in code form
def choose_storage(needs_acid, high_write_throughput, flexible_schema,
sub_ms_latency, graph_queries, global_scale):
if sub_ms_latency:
return 'Redis (in-memory key-value)'
if graph_queries:
return 'Neo4j (graph database)'
if needs_acid:
return 'PostgreSQL / MySQL (relational)'
if high_write_throughput and not flexible_schema:
return 'Cassandra (wide-column, write-optimised)'
if flexible_schema:
return 'MongoDB (document store)'
if global_scale:
return 'DynamoDB or Cosmos DB (managed global KV/document)'
return 'PostgreSQL (safe default for most web apps)'
# Example scenarios
scenarios = [
{'needs_acid': True, 'high_write_throughput': False, 'flexible_schema': False,
'sub_ms_latency': False, 'graph_queries': False, 'global_scale': False},
{'needs_acid': False, 'high_write_throughput': True, 'flexible_schema': False,
'sub_ms_latency': False, 'graph_queries': False, 'global_scale': False},
{'needs_acid': False, 'high_write_throughput': False, 'flexible_schema': False,
'sub_ms_latency': True, 'graph_queries': False, 'global_scale': False},
]
for s in scenarios:
print(f'{choose_storage(**s)}')Çoklu Depolama: Birden Fazla Veri Deposu Kullanmak
Üretim sistemleri nadiren her şey için tek bir veritabanı kullanır. Çoklu depolama, sistemin her bölümü için doğru depolama teknolojisini kullanmak anlamına gelir. Tipik bir web uygulaması şunları kullanabilir: yetkili kullanıcı ve sipariş verileri için PostgreSQL, oturum depolama ve önbellekleme için Redis, tam metin arama için Elasticsearch, dosya depolama için S3 ve olay günlükleri ile analiz için Cassandra.
Ödünleşim şudur: her yeni veritabanı türüyle birlikte işletimsel karmaşıklık artar. Ekip, birden fazla sistemi korumalı, izlemeli ve yedeklemelidir. Tasarım gerekçesi: her iş yükünü doğru depolamayla eşleştirmenin sağladığı performans ve ölçeklenebilirlik kazanımları, büyük ölçekteki işletim maliyetinden daha ağır basar.
# Polyglot persistence in an e-commerce system
components = {
'User accounts, orders, payments': {
'storage': 'PostgreSQL',
'reason': 'ACID transactions (payment integrity), complex queries',
},
'Product catalogue': {
'storage': 'MongoDB or PostgreSQL with JSONB',
'reason': 'Flexible product attributes vary by category',
},
'Session tokens': {
'storage': 'Redis (with TTL)',
'reason': 'O(1) lookup, automatic expiry, high throughput',
},
'Product search': {
'storage': 'Elasticsearch',
'reason': 'Full-text search, faceted filtering, relevance scoring',
},
'Activity/event log': {
'storage': 'Cassandra or Kafka + S3',
'reason': 'High write throughput, append-only, time-series queries',
},
'Product images / videos': {
'storage': 'S3 + CloudFront CDN',
'reason': 'Cheap object storage, global distribution via CDN',
},
}
for component, info in components.items():
print(f'{component}:\n {info["storage"]}: {info["reason"]}\n')Depolama Türleri Arasında Dizinleme Stratejisi
Tüm depolama sistemleri, yazma işlemlerini yavaşlatma ve ek depolama alanı kullanma karşılığında okumaları hızlandırmak için dizinler kullanır. Depolama türleri arasındaki dizinlemeyi anlamak sistem tasarımı için kritik önem taşır:
- SQL: herhangi bir sütunda B-ağacı dizini; çok sütunlu sorgular için bileşik dizinler; tablo aramalarını önlemek için kapsayıcı dizinler
- MongoDB: herhangi bir alanda dizin; bileşik dizinler; otomatik süre dolumu için TTL dizinleri
- Cassandra: yerel olarak yalnızca bölümleme anahtarı ve kümeleme sütunları dizinlenir; ikincil dizinler pahalıdır
- Redis: aralık sorguları için dizin olarak sıralı kümeler; anahtar-değer depolarında geleneksel dizinlemeye gerek yoktur
# Indexing examples across storage types
# PostgreSQL: B-tree composite index
postgres_index = '''
CREATE INDEX idx_orders_user_created
ON orders(user_id, created_at DESC);
-- Optimises: SELECT * FROM orders WHERE user_id=? ORDER BY created_at DESC
'''
# MongoDB: compound index
mongo_index = '''
db.products.createIndex({ category: 1, price: -1 })
// Optimises: db.products.find({category:'Electronics'}).sort({price:-1})
'''
# Cassandra: cluster key ordering (built into table design)
cassandra_index = '''
-- No separate index needed; clustering key IS the index:
PRIMARY KEY (user_id, event_time) WITH CLUSTERING ORDER BY (event_time DESC)
'''
print('PostgreSQL:', postgres_index)
print('MongoDB:', mongo_index)
print('Cassandra:', cassandra_index)Mülakatlarda SQL ve NoSQL: Ne Söylemeli?
Bir sistem tasarımı mülakatında “SQL mi, NoSQL mi?” diye sorulduğunda asla tek kelimelik yanıt vermeyiniz. Bunun yerine şu yapıyı izleyiniz:
- İş yükünü belirtiniz: “Bu, karmaşık filtrelemeye sahip, okuma ağırlıklı bir iş yükü; bu nedenle…”
- Gereksinimi belirtiniz: “Finansal işlemler için güçlü tutarlılığa ihtiyacımız var; bu nedenle…”
- Seçimi belirtiniz: “Okuma replikalarına sahip PostgreSQL kullanırdım”
- Ödünleşimi belirtiniz: “Ödünleşim şu: yatay yazma ölçeklendirmesi parçalama gerektiriyor ve bu da karmaşıklık ekliyor”
- Bir alternatiften bahsediniz: “Yazma trafiği daha yüksek olsaydı DynamoDB'yi değerlendirebilirdik”
# Sample answer structure for 'SQL or NoSQL?'
def answer_storage_question(workload, consistency_need, scale):
print(f'Workload: {workload}')
print(f'Consistency: {consistency_need}')
print(f'Scale: {scale}')
print()
if 'financial' in workload.lower() or consistency_need == 'strong':
choice = 'PostgreSQL (ACID, strong consistency)'
tradeoff = 'Horizontal write scaling requires sharding'
alternative = 'Google Spanner for global transactions'
elif 'event' in workload.lower() or 'log' in workload.lower():
choice = 'Cassandra (high write throughput, time-series)'
tradeoff = 'Eventual consistency; queries limited to partition key'
alternative = 'Kafka + S3 for long-term event archival'
else:
choice = 'DynamoDB (managed, auto-scale, low latency)'
tradeoff = 'Limited query flexibility; cross-item transactions limited'
alternative = 'PostgreSQL if complex queries emerge'
print(f'Choice: {choice}\nTrade-off: {tradeoff}\nAlternative: {alternative}')
answer_storage_question('Social media feed', 'eventual', '10M users')Hızlı Kontrol
Bu derste ele alınan Veri Yapıları & Algoritmalar — Kodlama Mülakatı Hazırlığı konularını ne kadar anladığınızı sınayınız.
Ders Özeti
Bu derste şunları öğrendiniz: SQL veritabanları ACID işlemleri ve karmaşık sorgular sunar, ancak yazma işlemlerini ölçeklendirmekte zorlanır; NoSQL veritabanları ise aşırı ölçek ve kullanılabilirlik karşılığında tutarlılıktan veya sorgu esnekliğinden ödün verir; CAP teoremi, ağ bölünmeleri sırasında dağıtık sistemleri tutarlılık ile kullanılabilirlik arasında seçim yapmaya zorlar; ayrıca üretim sistemleri genellikle çoklu depolama kullanır ve her iş yükünü doğru depolama altyapısıyla eşleştirir. Sırada, okuma ağırlıklı sistemleri daha da ölçeklendirmek için önbellekleme katmanlarını, içerik dağıtım ağlarını ve yük dengelemesini inceleyeceğiz.
Sıkça Sorulan Sorular
“Ölçeklenebilir Veri Depolama: SQL ve NoSQL” dersi ücretsiz mi?
Evet — “Ölçeklenebilir Veri Depolama: SQL ve NoSQL” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DSA Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DSA Interview Prep kursu toplamda 4 dersten oluşur.
“Ölçeklenebilir Veri Depolama: SQL ve NoSQL” dersinde ne öğreneceğim?
Erişim örüntülerine, tutarlılığa ve ölçek gereksinimlerine göre ilişkisel veritabanları, anahtar-değer depoları, belge veritabanları ve geniş sütunlu depolar arasından seçim yapın. DSA Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
DSA Interview Prep öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te DSA Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“Ölçeklenebilir Veri Depolama: SQL ve NoSQL” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu DSA Interview Prep dersinde kod yazıp çalıştırabilir miyim?
Evet. Her DSA Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Sistem Tasarımı Mülakatı Çerçevesi
- Ölçeklenebilir Veri Depolama: SQL ve NoSQL
- Önbelleğe Alma, CDN’ler ve Yük Dengeleme
- Hız Sınırlayıcı ve Twitter Akışı Tasarlama