Featured image of post SQL vs. NoSQL: Mô hình tư duy 'Thư viện vs Nhà kho'

SQL vs. NoSQL: Mô hình tư duy 'Thư viện vs Nhà kho'

Tại sao MongoDB nhanh nhưng Postgres lại an toàn hơn? Hướng dẫn chuyên sâu về Schema, ACID và tại sao JSONB có thể là thứ NoSQL duy nhất bạn cần.

“Nên dùng Postgres hay MongoDB?”

Câu hỏi này gây ra những cuộc chiến bàn phím ác liệt còn hơn cả “Vim vs. Emacs”.

Phe SQL bảo: “NoSQL làm mất dữ liệu. Nó chỉ là đồ chơi.” Phe NoSQL bảo: “SQL quá cứng nhắc. Nó không scale được.”

Cả hai đều sai. Đơn giản là chúng sinh ra để làm những việc khác nhau.

Đây là Hướng dẫn chuyên sâu về Database. Chúng ta sẽ dùng mô hình “Thư viện vs. Nhà kho” để hiểu chính xác khi nào dùng cái nào (và tại sao Postgres có thể là thứ duy nhất bạn cần).


Phần 1: Nền tảng (Mô hình tư duy)

SQL = Thư viện Công cộng

Hãy nghĩ về Relational Database (SQL) như một Thư viện được tổ chức hoàn hảo.

  • Schema (Hệ thống phân loại): Bạn không thể ném bừa một cuốn sách lên kệ nếu không biết chính xác nó thuộc về đâu. Tên tác giả, Mã sách (ISBN) phải tuân thủ quy tắc nghiêm ngặt.
  • Relations (Mối quan hệ): Sách liên kết với Tác giả. Nếu bạn xóa một ông Tác giả, bạn phải quyết định làm gì với đống sách của ông ấy (Xóa theo? Hay giữ lại?).
  • Điểm mạnh: Tính nhất quán (Consistency). Nếu danh mục bảo sách có ở đó, thì chắc chắn nó ở đó.
  • Điểm yếu: Sự cứng nhắc (Rigidity). Nếu bạn muốn lưu trữ một vật thể lạ (như một bức tượng 3D), bạn bó tay vì nó không vừa với cái kệ sách nào cả.

NoSQL = Cái Nhà kho khổng lồ

Hãy nghĩ về Document Database (NoSQL) như một cái Nhà kho Amazon.

  • Schema-less (Cái hộp): Bạn cứ ném đồ vào hộp. Hộp này đựng sách, hộp kia đựng giày, hộp nọ đựng ván lướt sóng. Nhà kho không quan tâm.
  • Denormalization: Bạn không liên kết đôi giày với ông thợ giày. Bạn viết tên ông thợ giày ngay bên trong hộp giày luôn.
  • Điểm mạnh: Linh hoạt & Tốc độ. Bạn lưu cái gì cũng được, ngay lập tức, không cần xin phép ai.
  • Điểm yếu: Sự hỗn loạn. Nếu ông thợ giày đổi tên, bạn phải chạy đi tìm cả triệu cái hộp giày để sửa lại tên ông ấy trên từng hộp.

Phần 2: Logic (ACID vs. BASE)

Đây là sự đánh đổi kỹ thuật thực sự.

1. SQL yêu ACID

  • Atomicity (Nguyên tử): “Được ăn cả, ngã về không”. Chuyển tiền từ A sang B. Nếu B lỗi nhận tiền, A được hoàn tiền ngay lập tức.
  • Consistency (Nhất quán): Dữ liệu không bao giờ phá vỡ luật lệ (constraint).
  • Isolation (Cô lập): Không ai nhìn thấy tiền đang chuyển cho đến khi nó xong hẳn.
  • Durability (Bền vững): Một khi đã báo “Saved”, là nó nằm hòm vĩnh viễn (kể cả mất điện).

2. NoSQL yêu BASE

  • Basic Availability: Hệ thống luôn luôn trả lời, kể cả khi một phần bị lỗi.
  • Soft state: Dữ liệu có thể thay đổi mà không cần bạn ghi (quá trình đồng bộ).
  • Eventual consistency (Nhất quán cuối cùng): Nếu bạn ngừng ghi, sau một lúc mọi người sẽ thấy dữ liệu giống nhau. (Nhưng trong vài giây, User A có thể thấy giá cũ, User B thấy giá mới).

Quy tắc bỏ túi:

  • App Ngân hàng? Kho vận? SQL (ACID). Bạn không thể chấp nhận việc số dư tài khoản “từ từ rồi đúng” được.
  • Like Facebook? Log chat? NoSQL (BASE). Nếu một cái Like hiện lên chậm 2 giây, chẳng ai chết cả.

Phần 3: Điều tra (Debug như chuyên gia)

1. “Thuế” JOIN (SQL)

Tại sao SQL chậm khi scale to? Vì Joins. Để lấy “User Profile”, SQL phải chạy đi hỏi 5 bảng (User, Address, Orders, Preferences, History).

  • Cái giá: Tốn CPU.
  • Scale: Rất khó để chia nhỏ ra nhiều server (Sharding mà dính Join là ác mộng).

2. “Thuế” Lặp dữ liệu (NoSQL)

NoSQL đọc cực nhanh vì “User Profile” chỉ là một document duy nhất. Lôi một phát là ra hết. Nhưng nếu User đổi Email thì sao?

  • SQL: Update 1 dòng trong bảng users. Xong.
  • NoSQL: Tìm User doc. Tìm 50 cái Order docs của nó. Tìm 100 cái Comment docs của nó. Đi update lại cái email trong TẤT CẢ chỗ đó.
  • Cái giá: Tốn công ghi (Write intensive) và code phức tạp để giữ đồng bộ.

Phần 4: Giải pháp (Postgres là chân ái)

Với 95% dự án, câu trả lời là: Cứ dùng Postgres đi.

Tại sao? Vì Postgres có JSONB.

Mô hình Lai (Hybrid)

Bạn có thể có các bảng quan hệ chặt chẽ VÀ các document linh hoạt trong cùng một database.

1
2
3
4
5
6
7
-- Dùng cả hai thế giới
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    user_id INT REFERENCES users(id),  -- Quan hệ chặt (An toàn)
    created_at TIMESTAMP,              -- Thời gian chuẩn (Sort ngon)
    payload JSONB                      -- Document linh hoạt (NoSQL)
);

Tại sao JSONB lại xịn?

  1. Lưu trữ nhị phân: Nó được nén gọn (không phải lưu chuỗi text như MySQL cũ).
  2. Đánh Index được: Bạn có thể tạo index cho một trường nằm sâu bên trong JSON.
    1
    2
    3
    
    -- Tìm tất cả event có payload -> 'status' là 'failed'
    -- Nhanh hơn cả MongoDB trong nhiều bài benchmark!
    CREATE INDEX idx_status ON events ((payload->>'status'));
    

Mô hình tư duy chốt hạ

1
2
3
4
SQL (Postgres) -> Thư viện. Dùng cho dữ liệu quan trọng, có cấu trúc (User, Tiền).
NoSQL (Mongo)  -> Nhà kho. Dùng cho log khổng lồ, không cấu trúc hoặc làm Prototype.

Postgres JSONB -> Cái Thư viện có xây thêm cái Nhà kho dưới hầm.

Hãy bắt đầu với SQL. Nếu chưa chốt được schema, cứ dùng cột JSONB. Chỉ chuyển sang NoSQL thuần túy nếu bạn có dữ liệu hàng PetaBytes hoặc nhu cầu quá đặc thù (Graph, TimeSeries) mà SQL bó tay.

Được tạo với sự lười biếng tình yêu 🦥

Subscribe to My Newsletter