Penyimpanan Data Boleh Skala: SQL berbanding NoSQL
Pilih antara pangkalan data hubungan, stor nilai-kunci, pangkalan data dokumen dan stor lajur lebar berdasarkan corak akses, ketekalan dan keperluan penskalaan.
Penyimpanan Data Boleh Skala: SQL berbanding NoSQL ialah pelajaran Persediaan Temu Duga Pengaturcaraan percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Persediaan Temu Duga Pengaturcaraan, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.
Pemilihan Storan Melibatkan Pertukaran
Memilih stor data ialah salah satu keputusan paling penting dalam reka bentuk sistem. Tiada pangkalan data yang terbaik untuk semua keadaan — setiap jenis dioptimumkan untuk corak capaian, jaminan konsistensi dan ciri skala yang berbeza. Kesilapan dalam pengeluaran boleh menyebabkan kerja pemindahan yang sukar selama berbulan-bulan.
Dalam temu duga, penemuduga ingin mengetahui sama ada anda memahami perbezaan asas dan boleh memadankan enjin storan dengan keperluan sesuatu masalah. Soalannya bukanlah “yang mana lebih baik?” tetapi “yang mana lebih baik untuk beban kerja khusus ini?” Sentiasa berikan justifikasi pilihan anda berdasarkan keperluan yang khusus.
# 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}')Pangkalan Data Hubungan (SQL): Kekuatan
Pangkalan data hubungan (PostgreSQL, MySQL, SQLite) menyimpan data dalam jadual dengan skema tetap dan menyokong transaksi ACID — Atomik, Konsistensi, Pengasingan dan Ketahanan. Pangkalan data ini cemerlang dalam pertanyaan kompleks yang menggunakan cantuman, pengagregatan dan penapis, menjadikannya sesuai untuk data berstruktur dengan hubungan yang jelas.
Kekuatan utama: pertanyaan berbilang jadual yang kompleks melalui SQL, kekangan kunci asing untuk integriti data, pengindeksan berkuasa (B-tree, cincangan, teks penuh), serta ekosistem matang dengan replikasi dan sandaran. Gunakan SQL apabila data anda sangat berkaitan, konsistensi amat penting dan pertanyaan adalah kompleks serta pelbagai.
# 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)Cabaran Penskalaan SQL
Pangkalan data SQL secara semula jadi diskalakan secara menegak (pelayan lebih besar, lebih banyak CPU/RAM), tetapi penskalaan mendatar adalah kompleks. Replika baca mengendalikan beban kerja yang berat pada bacaan dengan menghalakan bacaan kepada nod replika dan penulisan kepada nod utama. Namun, daya pemprosesan penulisan terhad kepada satu nod utama melainkan anda menambah pembahagian data.
Pembahagian data membahagikan data merentas beberapa instans pangkalan data berdasarkan kunci pembahagian (contohnya, user_id mod N). Kaedah ini meningkatkan skala penulisan tetapi menghapuskan cantuman dan transaksi merentas pembahagian — dua ciri SQL yang paling kukuh. Kebanyakan aplikasi web melebihi kemampuan SQL satu nod apabila mempunyai sekitar 5-10 TB data atau kira-kira 100K penulisan sesaat.
# 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')Stor Kunci-Nilai: Redis dan DynamoDB
Stor kunci-nilai menyimpan data sebagai pasangan kunci → nilai dengan bacaan dan penulisan O(1) pada kunci tersebut. Stor ini mengorbankan fleksibiliti pertanyaan demi prestasi yang sangat tinggi dan kebolehskalaan mendatar. Redis (dalam memori) mencapai kependaman mikrosaat; DynamoDB (terurus) mencapai kependaman milisaat satu digit dengan penskalaan automatik kepada sebarang kadar pemprosesan.
Gunakan stor kunci-nilai untuk: storan sesi, cache, penanda ciri, pemetaan pemendek URL, troli beli-belah dan papan pendahulu masa nyata. Jangan gunakannya apabila anda memerlukan: pertanyaan kompleks, hubungan antara entiti atau penapisan spontan — anda hanya boleh mencari berdasarkan kunci yang tepat.
# 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')Stor Dokumen: MongoDB
Stor dokumen (MongoDB, Couchbase) menyimpan data sebagai dokumen seperti JSON, yang membolehkan skema fleksibel — medan boleh berbeza antara dokumen dalam koleksi yang sama. Stor ini menyokong pengindeksan pada mana-mana medan serta pertanyaan yang agak kaya (penapis, unjuran dan pengagregatan), walaupun transaksi berbilang dokumen lebih terhad berbanding SQL.
Stor dokumen sesuai untuk aplikasi yang: bentuk datanya berbeza mengikut entiti (profil pengguna dengan atribut yang berbeza), menjangkakan perubahan skema yang pantas (syarikat baharu yang kerap mengubah model data), atau corak bacaannya lebih banyak mendapatkan keseluruhan entiti berbanding mencantumkan jadual.
# 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')Stor Lajur Lebar: Cassandra
Stor lajur lebar (Apache Cassandra, HBase) menyimpan data dalam baris dan lajur tetapi membenarkan setiap baris mempunyai set lajur yang berbeza. Stor ini direka untuk daya pemprosesan penulisan yang sangat besar yang diagihkan merentas banyak nod, dengan konsistensi akhirnya sebagai tetapan lalai. Cassandra mencapai skala penulisan linear — menggandakan bilangan nod menggandakan daya pemprosesan penulisan.
Pertukarannya: pertanyaan mesti direka berdasarkan kunci pembahagian. Anda tidak boleh menapis atau sort pada lajur sewenang-wenangnya dengan cekap — anda mesti menentukan corak pertanyaan dahulu, kemudian mereka bentuk jadual yang sepadan dengannya. Ini bertentangan dengan pendekatan SQL “reka bentuk data dahulu, kemudian tulis apa-apa pertanyaan”.
# 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)')Teorem CAP: Konsistensi, Ketersediaan, Toleransi Pembahagian
Teorem CAP menyatakan bahawa sistem teragih boleh menjamin paling banyak dua daripada perkara berikut: Konsistensi (setiap bacaan mengembalikan penulisan terkini), Ketersediaan (setiap permintaan menerima respons tanpa ralat) dan Toleransi pembahagian (sistem terus beroperasi walaupun berlaku pembahagian rangkaian).
Memandangkan pembahagian rangkaian sentiasa boleh berlaku dalam sistem teragih, pilihan sebenar ialah antara CP (mengutamakan konsistensi dan mungkin menolak permintaan semasa pembahagian) dengan AP (mengutamakan ketersediaan dan mungkin mengembalikan data lapuk). Pangkalan data SQL secara amnya ialah CP; Cassandra dan DynamoDB ialah AP (konsistensi akhirnya secara lalai). Kluster Redis ialah CP.
# 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"]}')Memilih Storan: Rangka Kerja Membuat Keputusan
Rangka kerja praktikal untuk membuat keputusan tentang pilihan storan dalam temu duga:
- Perlukan transaksi ACID? → Pangkalan data hubungan (PostgreSQL, MySQL)
- Perlukan carian bawah satu milisaat atau cache? → Stor kunci-nilai (Redis)
- Perlukan skema fleksibel atau data berorientasikan dokumen? → Stor dokumen (MongoDB)
- Perlukan daya pemprosesan penulisan yang sangat besar (>100K/saat) dengan data siri masa atau peristiwa? → Stor lajur lebar (Cassandra)
- Perlukan pengedaran global dengan penskalaan terurus? → DynamoDB atau Cosmos DB
- Perlukan lintasan graf? → Pangkalan data graf (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)}')Kegigihan Poliglot: Menggunakan Berbilang Stor
Sistem pengeluaran jarang menggunakan satu pangkalan data untuk segala-galanya. Kegigihan poliglot bermaksud menggunakan teknologi storan yang sesuai untuk setiap bahagian sistem. Aplikasi web biasa mungkin menggunakan: PostgreSQL untuk data pengguna dan pesanan yang menjadi sumber rujukan, Redis untuk storan sesi dan cache, Elasticsearch untuk carian teks penuh, S3 untuk storan fail dan Cassandra untuk log peristiwa serta analitik.
Pertukarannya: kerumitan operasi meningkat dengan setiap jenis pangkalan data. Pasukan perlu menyelenggara, memantau dan membuat sandaran bagi berbilang sistem. Justifikasi reka bentuk: peningkatan prestasi dan kebolehskalaan hasil pemadanan setiap beban kerja dengan storan yang sesuai mengatasi kos operasi pada skala besar.
# 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')Strategi Pengindeksan Merentas Jenis Storan
Semua sistem storan menggunakan indeks untuk mempercepat bacaan, dengan mengorbankan penulisan yang lebih perlahan dan storan tambahan. Memahami pengindeksan merentas jenis storan amat penting untuk reka bentuk sistem:
- SQL: indeks B-tree pada mana-mana lajur; indeks gabungan untuk pertanyaan berbilang lajur; indeks liputan untuk mengelakkan carian jadual
- MongoDB: indeks pada mana-mana medan; indeks kompaun; indeks TTL untuk tamat tempoh automatik
- Cassandra: hanya kunci pembahagian dan lajur pengelompokan diindeks secara asli; indeks sekunder adalah mahal
- Redis: set tersusun sebagai indeks pertanyaan julat; pengindeksan tradisional tidak diperlukan untuk stor kunci-nilai
# 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)SQL berbanding NoSQL dalam Temu Duga: Perkara yang Perlu Dikatakan
Apabila ditanya “SQL atau NoSQL?” dalam temu duga reka bentuk sistem, jangan sekali-kali berikan jawapan satu perkataan. Sebaliknya, ikut struktur ini:
- Nyatakan beban kerja: “Beban ini berat pada bacaan dengan penapisan kompleks, jadi…”
- Nyatakan keperluan: “Kami memerlukan konsistensi kukuh untuk transaksi kewangan, jadi…”
- Nyatakan pilihan: “Saya akan menggunakan PostgreSQL dengan replika baca”
- Nyatakan pertukaran: “Pertukarannya ialah penskalaan penulisan mendatar memerlukan pembahagian data, yang menambah kerumitan”
- Sebut satu alternatif: “Jika kadar penulisan lebih tinggi, kami mungkin mempertimbangkan DynamoDB”
# 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')Semakan Pantas
Uji pemahaman anda tentang konsep Struktur Data & Algoritma — Persediaan Temu Duga Pengekodan daripada pelajaran ini.
Ringkasan Pelajaran
Dalam pelajaran ini, anda mempelajari: pangkalan data SQL menyediakan transaksi ACID dan pertanyaan kompleks tetapi sukar menskalakan penulisan, manakala pangkalan data NoSQL mengorbankan konsistensi atau fleksibiliti pertanyaan demi skala dan ketersediaan yang sangat tinggi, teorem CAP memaksa sistem teragih memilih antara konsistensi dan ketersediaan semasa pembahagian rangkaian, dan sistem pengeluaran biasanya menggunakan kegigihan poliglot — memadankan setiap beban kerja dengan enjin storan yang sesuai. Seterusnya, kita akan meneroka lapisan cache, CDN dan pengimbangan beban untuk meningkatkan lagi skala sistem yang berat pada bacaan.
Pelajari Persediaan Temu Duga Pengaturcaraan dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 90
- Pelajaran
- 360
Soalan Lazim
Adakah pelajaran “Penyimpanan Data Boleh Skala: SQL berbanding NoSQL” percuma?
Ya — teks penuh “Penyimpanan Data Boleh Skala: SQL berbanding NoSQL” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Persediaan Temu Duga Pengaturcaraan, tingkat taraf kepada CoddyKit PRO. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Penyimpanan Data Boleh Skala: SQL berbanding NoSQL”?
Pilih antara pangkalan data hubungan, stor nilai-kunci, pangkalan data dokumen dan stor lajur lebar berdasarkan corak akses, ketekalan dan keperluan penskalaan. Anda berlatih Persediaan Temu Duga Pengaturcaraan menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Persediaan Temu Duga Pengaturcaraan?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Persediaan Temu Duga Pengaturcaraan di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.
Berapa lamakah pelajaran “Penyimpanan Data Boleh Skala: SQL berbanding NoSQL” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Persediaan Temu Duga Pengaturcaraan ini?
Ya. Setiap pelajaran Persediaan Temu Duga Pengaturcaraan menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Rangka Kerja Temu Duga Reka Bentuk Sistem
- Penyimpanan Data Boleh Skala: SQL berbanding NoSQL
- Pencachean, CDN dan Pengimbangan Beban
- Reka Bentuk Pembatas Kadar dan Reka Bentuk Suapan Twitter