[System Design Version 1 - Bài 7] Relational vs. NoSQL: Đừng chọn Database theo trend. Phân tích bài toán để chọn đúng công cụ
Chào anh em. Nếu anh em lướt qua các diễn đàn công nghệ, chắc hẳn không ít lần đọc được những bài viết sặc mùi "dìm hàng" kiểu như: "MySQL/PostgreSQL lỗi thời rồi, hệ thống hiện đại là phải dùng NoSQL (MongoDB, Cassandra)".
Hậu quả là một thế hệ các bạn dev trẻ cứ thấy project mới là auto cài MongoDB, bất chấp việc data có quan hệ chằng chịt với nhau. Để rồi vài tháng sau, chính các bạn ấy phải viết những vòng lặp for lồng nhau vô tận trong code chỉ để JOIN dữ liệu, và khóc ròng khi dữ liệu bị "rác" vì thiếu các ràng buộc (Foreign Keys).
Sau hơn 20 năm "ăn hành" với đủ loại cơ sở dữ liệu, tôi rút ra một chân lý: Database không có cái nào là "chân ái" của mọi thời đại. Chỉ có Database sinh ra để giải quyết đúng bài toán của nó.
1. Relational Database (SQL - MySQL, PostgreSQL): Kẻ gác đền nguyên tắc
Relational Database Management System (RDBMS) lưu dữ liệu dưới dạng bảng (Table) với các cột và hàng cố định. Sức mạnh tuyệt đối của nó nằm ở ACID (Atomicity, Consistency, Isolation, Durability).
Khi nào thì bắt buộc phải dùng SQL? Đó là khi tính toàn vẹn của dữ liệu (Data Integrity) và tính nhất quán (Consistency) là vấn đề sống còn.
- Bài toán thực tế: Hãy nhìn vào hệ thống thu phí tự động (AFC) của tuyến Metro hoặc một ứng dụng ví điện tử. Khi người dùng nạp tiền tại máy bán vé (TVM), giao dịch đó phải thành công trọn vẹn (trừ tiền ở ngân hàng VÀ cộng tiền vào thẻ) hoặc phải thất bại toàn bộ (Rollback). Không thể có chuyện tiền ở ngân hàng đã trừ mà thẻ chưa được cộng.
- Với Transaction chuẩn ACID của PostgreSQL hay MySQL, bạn sẽ ngủ ngon hàng đêm vì biết rằng hệ thống không bao giờ bị thất thoát dù chỉ 1 đồng. RDBMS sinh ra để xử lý những bài toán nặng về nghiệp vụ tài chính, đối soát, nơi mà dữ liệu có cấu trúc cực kỳ rõ ràng và quan hệ chặt chẽ.
Điểm yếu: Nó rất khó scale chiều ngang (Horizontal Scaling). Khi data quá to, bạn phải chia nhỏ (Sharding) rất đau đầu. Lược đồ (Schema) của nó cũng rất cứng nhắc, mỗi lần ALTER TABLE thêm cột ở Production là một lần tim đập chân run.
2. NoSQL (MongoDB, Couchbase): Sự linh hoạt của thời đại số
NoSQL (Document-oriented) lưu dữ liệu dưới dạng JSON/BSON. Không có bảng, không có cột cố định, không có khóa ngoại ràng buộc rườm rà.
Khi nào thì NoSQL tỏa sáng? Khi dữ liệu của bạn không có cấu trúc cố định và thay đổi liên tục.
- Bài toán thực tế: Hãy tưởng tượng bạn đang xây dựng backend cho một hệ thống e-commerce bán lẻ đồ mỹ phẩm. Bảng
Productscủa bạn sẽ trông như thế nào? - Thỏi son thì có thuộc tính
màu sắc,độ lì. - Kem dưỡng da thì có
độ ẩm,thành phần dị ứng. - Máy rửa mặt thì có
công suất,thời gian bảo hành,điện áp. - Nếu dùng MySQL, bạn sẽ phải tạo một cái bảng với hàng trăm cột rỗng (NULL), hoặc dùng mô hình EAV (Entity-Attribute-Value) cực kỳ chậm chạp khi query.
- Nhưng với MongoDB? Nó là thiên đường! Mỗi sản phẩm là một Document riêng biệt, bạn muốn nhét thêm thuộc tính gì vào cũng được. Nó cực kỳ phù hợp cho hệ thống Product Catalog, CMS, hoặc lưu trữ profile người dùng với các sở thích khác nhau.
3. NoSQL (Cassandra, DynamoDB): Quái vật cày cuốc (Write-heavy)
Có những hệ thống mà lượng dữ liệu ĐỌC rất ít, nhưng lượng GHI vào thì khổng lồ và dồn dập.
- Bài toán thực tế: Cổng soát vé (Gate) của nhà ga trong giờ cao điểm, hàng ngàn lượt quẹt thẻ mỗi phút. Hoặc hệ thống log hành vi người dùng (click vào đâu, cuộn chuột đến đâu).
- RDBMS sẽ bị nghẽn cổ chai ngay lập tức vì các cơ chế Locking. MongoDB cũng sẽ chật vật. Lúc này, bạn cần đến họ NoSQL cột rộng (Wide-column) như Cassandra. Nó được thiết kế với kiến trúc phi tập trung (Decentralized), cho phép ghi (Write) với tốc độ ánh sáng mà không cần quan tâm đến Lock, và scale chiều ngang dễ như ăn kẹo.
Lời kết
Đừng bao giờ thiết kế hệ thống theo kiểu: "Công ty em dùng MongoDB làm database chính". Một hệ thống kiến trúc tốt (đặc biệt là Microservices) sẽ áp dụng Polyglot Persistence.
Nghĩa là:
- Service Xử lý thanh toán/Đơn hàng? Cứ MySQL/PostgreSQL mà táng.
- Service Quản lý thông tin mỹ phẩm/Sản phẩm? Dùng MongoDB cho linh hoạt.
- Service Lưu trữ Log quẹt thẻ/Tracking người dùng? Quăng vào Cassandra hoặc Elasticsearch.
Phân tích đúng bản chất của luồng dữ liệu (Read-heavy hay Write-heavy, có cần ACID hay không), bạn sẽ chọn được đúng vũ khí.
Nhưng chờ đã... Dù bạn có dùng Database xịn đến đâu, cấu hình index tối ưu thế nào đi nữa, thì việc query trực tiếp vào ổ cứng (Disk) cũng không bao giờ có thể đáp ứng được hàng triệu lượt truy cập cùng lúc trong các đợt Flash Sale. Database của bạn sẽ "bốc khói".
Để cứu rỗi Database, chúng ta phải đưa dữ liệu lên RAM.
👉 Và đó là lúc nghệ thuật đỉnh cao xuất hiện ở bài tiếp theo: "Nghệ thuật Caching: Redis/Memcached. Chiến lược Cache (Cache-Aside, Write-Through). Vấn đề 'nhức nhối' như Cache Penetration, Cache Breakdown và Cache Avalanche."
Anh em đã từng khóc hận vì chọn sai Database bao giờ chưa? Cùng chia sẻ lại kỷ niệm đau thương dưới phần bình luận nhé!
All rights reserved