Giao diện
SQL vs NoSQL
"Dùng SQL hay NoSQL" là câu hỏi đặt sai. NoSQL không phải một loại database, mà là tên gọi chung cho nhiều loại rất khác nhau, mỗi loại tối ưu cho một kiểu truy cập. Trang này giải thích các nhóm NoSQL chính, chọn database theo mẫu truy cập như thế nào, và NewSQL là gì. CAP, PACELC và các mức nhất quán có trang chính ở Hệ phân tán › Nhất quán & CAP.
Database quan hệ giỏi ở đâu
Database quan hệ (MySQL, PostgreSQL) lưu dữ liệu thành bảng có schema, nối các bảng bằng JOIN, và đảm bảo transaction ACID trên nhiều bảng. Sức mạnh lớn nhất của nó là không cần biết trước sẽ query thế nào: dữ liệu được chuẩn hoá, mỗi sự thật lưu một chỗ (Chuẩn hoá), và gần như mọi câu hỏi mới đều viết được bằng SQL, thêm index là chạy nhanh.
Giới hạn của nó là scale ghi. Một database quan hệ chạy trên một primary, và muốn ghi vượt sức một máy thì phải sharding, tức tự chia dữ liệu và mất JOIN cũng như transaction giữa các shard (MySQL chương 10).
Các nhóm NoSQL
| Nhóm | Ví dụ | Mô hình | Giỏi ở | Đổi lại |
|---|---|---|---|---|
| Key–value | Redis, DynamoDB, Memcached | Mỗi key trỏ tới một giá trị | Đọc ghi theo key cực nhanh, scale ngang dễ | Chỉ tra được theo key (DynamoDB có thêm sort key và index phụ) |
| Document | MongoDB, Couchbase | Mỗi bản ghi là một document JSON lồng nhau | Dữ liệu có cấu trúc lồng, đọc cả object một lần, schema linh hoạt | JOIN yếu; dữ liệu lặp lại giữa các document thì phải tự giữ đồng bộ |
| Wide-column | Cassandra, ScyllaDB, HBase, Bigtable | Bảng phân theo partition key, trong mỗi partition dòng sắp theo clustering key | Ghi cực lớn, chia đều trên nhiều node, nhiều datacenter | Không JOIN; thiết kế bảng theo từng query, mỗi query một bảng |
| Graph | Neo4j, Amazon Neptune | Đỉnh và cạnh | Đi theo quan hệ nhiều bước: bạn của bạn, gợi ý, phát hiện gian lận | Không hợp với tổng hợp trên cả tập dữ liệu |
| Search | Elasticsearch, OpenSearch | Inverted index trên document | Tìm kiếm văn bản, xếp hạng, lọc nhiều chiều (Full-text search) | Thường không dùng làm nơi lưu dữ liệu chính |
| Time-series | InfluxDB, TimescaleDB, Prometheus | Chuỗi giá trị theo thời gian | Ghi liên tục, đọc theo khoảng, nén tốt (Chuỗi thời gian) | Chỉ hợp với dữ liệu dạng đó |
Ranh giới giữa các nhóm ngày càng mờ. PostgreSQL có JSONB và index GIN nên làm được nhiều việc của document store (EAV, JSON). MongoDB có transaction trên nhiều document. DynamoDB có transaction gom tới 100 thao tác ghi. Câu hỏi đúng là hệ thống này hợp với cách dữ liệu được đọc và ghi tới đâu.
Cùng một bài toán, mô hình khác nhau
Bài toán đơn hàng: mỗi đơn có khách hàng, nhiều dòng sản phẩm, địa chỉ giao. Các truy cập chính là xem chi tiết một đơn, liệt kê đơn của một khách theo thời gian, và báo cáo doanh thu theo sản phẩm.
- Quan hệ: bảng
orders,order_items,customers,products. Xem một đơn là JOIN vài bảng, liệt kê đơn của khách cần index(customer_id, created_at), báo cáo làGROUP BY. Mọi truy cập đều làm được, kể cả những truy cập chưa nghĩ tới. - Document (MongoDB): một document cho mỗi đơn, chứa luôn mảng sản phẩm và địa chỉ giao. Xem một đơn là đọc một document. Tên sản phẩm được chép vào từng đơn (thực ra là snapshot, đúng ý nghiệp vụ, xem Snapshot không phải phá chuẩn). Báo cáo theo sản phẩm thì phải gỡ mảng ra rồi gom (aggregation pipeline), chậm hơn SQL trên dữ liệu chuẩn hoá.
- Wide-column (Cassandra): bảng
orders_by_customervới partition key làcustomer_id, clustering key làcreated_atgiảm dần. Liệt kê đơn của một khách là đọc liền một partition, cực nhanh với bất kỳ lượng dữ liệu nào. Muốn tra đơn theo mã đơn thì cần thêm bảngorders_by_id, app ghi vào cả hai. Tài liệu Cassandra nói rõ việc thiết kế đi từ query, và vì không có JOIN nên mọi cột cần cho một query phải nằm chung một bảng. Báo cáo theo sản phẩm gần như phải làm ở hệ khác. - Key–value (DynamoDB): thường gom nhiều loại bản ghi vào một bảng với khoá được thiết kế theo truy cập (
PK = CUSTOMER#123,SK = ORDER#2025-06-01#9876). Mỗi bản ghi tối đa 400 KB. Rất nhanh và scale gần như vô hạn với đúng những truy cập đã thiết kế trước, còn truy cập mới thì thường phải thêm index phụ hoặc sửa lại cấu trúc khoá.
Bài học là NoSQL đổi sự linh hoạt của query lấy khả năng scale và tốc độ với những query đã biết trước. Database quan hệ thì ngược lại.
Chọn theo mẫu truy cập
| Nếu hệ thống cần | Hợp với |
|---|---|
| Transaction trên nhiều bản ghi, ràng buộc toàn vẹn, tiền bạc, tồn kho | Database quan hệ |
| Query linh hoạt, báo cáo, câu hỏi chưa biết trước | Database quan hệ, cộng một hệ phân tích cho báo cáo lớn (OLTP vs OLAP) |
| Truy cập theo key với lượng cực lớn, latency thấp, tự scale | Key–value (DynamoDB), cache (Redis) |
| Ghi liên tục rất lớn, nhiều datacenter, query theo một khoá biết trước | Wide-column (Cassandra) |
| Object lồng nhau đọc trọn một lần, schema thay đổi nhanh | Document (MongoDB), hoặc JSONB trong PostgreSQL |
| Đi theo quan hệ nhiều bước | Graph |
| Tìm kiếm văn bản | Search engine, đồng bộ từ database chính |
Một hệ thống thật thường dùng nhiều loại: database quan hệ cho dữ liệu nghiệp vụ, Redis cho cache và bộ đếm, search engine cho tìm kiếm, kho phân tích cho báo cáo. Mỗi thứ thêm vào là thêm một hệ thống phải vận hành và phải đồng bộ dữ liệu, nên trong phỏng vấn nên bắt đầu bằng một database quan hệ và chỉ thêm khi chỉ ra được truy cập cụ thể nào nó không đáp ứng được (Phân tích bài toán).
NewSQL
NewSQL, hay distributed SQL, là nhóm database cố giữ cả hai: SQL và transaction ACID như database quan hệ, cộng scale ngang tự động như NoSQL. Dữ liệu tự chia thành nhiều phần trên nhiều node, mỗi phần được replicate bằng consensus (Consensus), và transaction đi qua nhiều phần dùng commit phân tán (Commit phân tán).
| Hệ thống | Tương thích với |
|---|---|
| Google Spanner | SQL riêng và một chế độ tương thích PostgreSQL; dùng TrueTime (Thời gian) |
| CockroachDB | Giao thức PostgreSQL |
| YugabyteDB | PostgreSQL |
| TiDB | Giao thức MySQL |
Cái giá là latency ghi cao hơn: mỗi lệnh ghi phải chờ đa số replica xác nhận, và transaction chạm nhiều phần dữ liệu còn chờ thêm commit phân tán. Khi replica nằm ở nhiều vùng xa nhau, một lệnh ghi có thể mất hàng chục tới hàng trăm ms. NewSQL hợp khi thật sự cần cả transaction lẫn scale ghi vượt một máy, hoặc cần chạy ở nhiều vùng mà vẫn nhất quán. Với phần lớn hệ thống, một database quan hệ có replica vẫn đủ và rẻ hơn nhiều.
Ghi nhớ
- NoSQL là nhiều loại khác nhau (key–value, document, wide-column, graph, search, time-series), mỗi loại tối ưu cho một kiểu truy cập.
- Database quan hệ mạnh ở query linh hoạt và transaction nhiều bảng; NoSQL đổi sự linh hoạt đó lấy scale và tốc độ với những query biết trước.
- Wide-column và key–value thiết kế bảng theo từng query, không có JOIN; truy cập mới thường cần thêm bảng hoặc index phụ.
- Chọn theo mẫu truy cập, bắt đầu bằng database quan hệ và chỉ thêm hệ khác khi chỉ ra được truy cập nó không đáp ứng được.
- NewSQL giữ SQL và ACID trên nhiều node nhờ consensus, đổi lại latency ghi cao hơn.
Nguồn tham khảo
Đã đối chiếu (đọc nguồn ngày 2026-10-23):
| Nguồn | Dùng cho phần |
|---|---|
| Apache Cassandra docs, Data modeling | Thiết kế đi từ query; không có JOIN nên mọi cột cần cho một query phải nằm chung một bảng |
| AWS docs, DynamoDB quotas and constraints, DynamoDB transactions | Mỗi item tối đa 400 KB; TransactWriteItems gom tới 100 thao tác ghi |
| MongoDB docs, Transactions | Có transaction nhiều document, nhưng nhiều trường hợp không cần vì dữ liệu liên quan nằm chung một document |
Từ kiến thức chung, chưa đối chiếu lần này: mô hình của từng nhóm NoSQL và các ví dụ hệ thống; mức tương thích của Spanner, CockroachDB, YugabyteDB, TiDB; latency ghi của NewSQL nhiều vùng.