SQL vs NoSQL — Chọn Database Cho Dự Án Của Bạn
So sánh SQL và NoSQL: relational vs document, scaling, use case — giúp bạn chọn đúng database.
Chọn database là một trong những quyết định quan trọng nhất khi thiết kế hệ thống. SQL hay NoSQL? Câu trả lời: “tùy”.
SQL — Structured Query Language#
Ví dụ: PostgreSQL, MySQL, SQLite, MariaDB, SQL Server
Đặc điểm#
- Schema cố định — bảng, cột, kiểu dữ liệu định nghĩa trước
- ACID — Atomicity, Consistency, Isolation, Durability
- Relations — JOIN giữa các bảng qua foreign key
- Mature — 50+ năm phát triển, tooling phong phú
Khi nào dùng SQL#
-- Dữ liệu có quan hệ rõ ràng
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
total DECIMAL(10,2),
created_at TIMESTAMP DEFAULT NOW()
);
-- Cần JOIN, transaction, consistency
SELECT u.name, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id
HAVING COUNT(o.id) > 5;sqlUse case: Finance, ERP, CRM, hệ thống cần consistency mạnh.
NoSQL — Not Only SQL#
Ví dụ: MongoDB (Document), Redis (Key-Value), Cassandra (Wide-column), Neo4j (Graph)
Document DB (MongoDB)#
// Schema-less — mỗi document có thể khác nhau
{
"_id": "user_123",
"name": "Alice",
"email": "alice@example.com",
"orders": [
{ "id": "ord_1", "total": 100, "items": ["item_a", "item_b"] },
{ "id": "ord_2", "total": 50 }
]
}jsonƯu: Linh hoạt, không cần migration, dữ liệu lồng nhau tự nhiên. Nhược: Không JOIN, không ACID mạnh (MongoDB có transaction nhưng limited).
Key-Value (Redis)#
SET user:123 '{"name":"Alice","email":"alice@example.com"}'
SET session:abc123 user_123 EX 3600
LPUSH notifications:user_123 "New message"bashƯu: Siêu nhanh (in-memory), đơn giản. Nhược: Không query phức tạp, dữ liệu phải fit memory.
Wide-column (Cassandra)#
CREATE TABLE user_events (
user_id UUID,
event_time TIMESTAMP,
event_type TEXT,
data TEXT,
PRIMARY KEY (user_id, event_time)
);sqlƯu: Scale ngang cực tốt, write throughput cao. Nhược: Query pattern phải biết trước, không JOIN.
Graph (Neo4j)#
MATCH (u:User {id: '123'})-[:FOLLOWS]->(f:User)-[:POSTED]->(p:Post)
RETURN pcypherƯu: Quan hệ phức tạp, recommendation, social graph. Nhược: Không tốt cho simple CRUD.
So Sánh#
| Tiêu chí | SQL | NoSQL |
|---|---|---|
| Schema | Cố định, rigid | Linh hoạt, dynamic |
| ACID | Mạnh (full ACID) | Yếu hơn (tùy loại) |
| JOIN | Tốt, built-in | Không hoặc limited |
| Scale | Vertical (chính) | Horizontal (dễ) |
| Query | SQL chuẩn, mạnh | Tùy database |
| Consistency | Strong | Eventual (thường) |
| Maturity | Cao | Trung bình |
CAP Cho Database#
SQL (PostgreSQL): CP — ưu tiên Consistency
MongoDB: CP (mặc định) hoặc AP
Cassandra: AP — ưu tiên Availability
Redis: CP (single node) hoặc AP (cluster)plaintextKhi Nào Chọn SQL#
- Dữ liệu có quan hệ chặt chẽ (user-order-product)
- Cần transaction (chuyển tiền, đặt hàng)
- Query phức tạp, nhiều JOIN
- Schema ổn định, ít thay đổi
- Consistency là ưu tiên hàng đầu
Khi Nào Chọn NoSQL#
- Schema thay đổi thường xuyên (MVP, poc)
- Cần scale ngang lớn (millions của users)
- Dữ liệu nested tự nhiên (JSON, document)
- Cache, session, real-time (Redis)
- Time-series data, event logging (Cassandra, InfluxDB)
- Social graph, recommendation (Neo4j)
Polyglot Persistence — Dùng Cả Hai#
Nhiều hệ thống dùng nhiều database cho nhiều mục đích:
PostgreSQL → Dữ liệu chính (orders, users, products)
Redis → Cache, session, rate limiting
MongoDB → Content, bài viết, log
Elasticsearch → Full-text searchplaintextKhông có luật nào cấm dùng cả SQL và NoSQL trong cùng project.
Migration từ SQL sang NoSQL#
// SQL: users table + orders table → JOIN
// NoSQL: embedded orders trong user document
// MongoDB
db.users.insertOne({
name: 'Alice',
orders: [
{ id: 1, total: 100, items: ['laptop'] },
{ id: 2, total: 50, items: ['mouse'] }
]
});
// Nếu orders quá nhiều → reference thay vì embed
db.users.findOne({ _id: 'user_123' })
// Sau đó query orders riêng
db.orders.find({ user_id: 'user_123' })javascriptKết Luận#
SQL không chết, NoSQL không phải thần dược. Chọn theo:
- Dữ liệu có quan hệ? → SQL
- Cần ACID? → SQL
- Cần scale ngang? → NoSQL
- Schema thay đổi liên tục? → NoSQL
- Phân tích real-time? → NoSQL (Cassandra, ClickHouse)
Hay nhất: biết cả hai. Dự án thực tế thường dùng PostgreSQL + Redis.