0

Elasticsearch Bài học 4: Tư duy chuyển đổi - So sánh mô hình dữ liệu Elasticsearch (NoSQL) vs Relational Database (RDBMS)

Khi xây dựng backend cho các nền tảng e-commerce hay hệ thống vận hành phức tạp (như logistics, vé điện tử), rào cản lớn nhất khi chuyển sang Elasticsearch không nằm ở cú pháp API, mà nằm ở tư duy thiết kế dữ liệu.

Nếu mang nguyên xi cách thiết kế bảng của MySQL hay PostgreSQL (RDBMS) đắp sang Elasticsearch, hệ thống của bạn sẽ nhanh chóng trở thành một mớ bòng bong với hiệu năng thảm hại. Để làm chủ Elasticsearch, bạn cần một cú "lật mặt" về tư duy hệ thống.

1. Chuẩn hóa (Normalization) vs. Phi chuẩn hóa (Denormalization)

Đây là điểm khác biệt sống còn nhất giữa hai thế giới.

Trong RDBMS (MySQL/Postgres): Luật bất thành văn là phải chuẩn hóa (Normalize) dữ liệu (thường là dạng chuẩn 3NF). Tránh lưu trữ lặp lại. Nếu có một bảng products, bạn sẽ không lưu tên danh mục vào đó. Bạn lưu category_id và dùng lệnh JOIN với bảng categories khi cần đọc. RDBMS cực kỳ xuất sắc trong việc thực thi các lệnh JOIN cục bộ trên một server.

Trong Elasticsearch: Elasticsearch là một hệ thống phân tán. Dữ liệu của bạn nằm rải rác trên nhiều Shards, đặt tại nhiều Node (Server) khác nhau. Việc thực hiện JOIN qua lại giữa các Node qua mạng lưới (Network) là một thảm họa về hiệu năng (Network latency). Tư duy ở đây là Phi chuẩn hóa (Denormalization): Dữ liệu đọc cùng nhau thì phải được lưu cùng nhau trong một Document (Tài liệu JSON). Lưu trữ (Disk) thì rẻ, nhưng CPU để tính toán JOIN phân tán thì vô cùng đắt đỏ.

Thay vì tách bảng, một Document trong Elasticsearch sẽ lưu "phẳng" (flatten) mọi thứ:

JSON

{
  "product_id": "SP12345",
  "name": "Sữa rửa mặt Cetaphil 500ml",
  "price": 250000,
  "category": {
    "id": 12,
    "name": "Chăm sóc da mặt"
  },
  "brand": {
    "id": 4,
    "name": "Cetaphil"
  }
}

Nhờ cấu trúc này, khi user search, Elasticsearch chỉ cần quét 1 lần là lấy ra toàn bộ thông tin sản phẩm, danh mục, thương hiệu mà không cần bất kỳ phép JOIN nào.

2. Schema khắt khe vs. Dynamic Mapping linh hoạt

Trong MySQL: Bạn phải định nghĩa Schema từ đầu. CREATE TABLE với các cột VARCHAR, INT, DATETIME rạch ròi. Muốn thêm một trường mới? Bạn phải chạy ALTER TABLE (đôi khi gây lock table và downtime trên production).

Trong Elasticsearch: Dữ liệu được đưa vào dưới dạng JSON. Nhờ tính năng Dynamic Mapping, khi bạn ném một file JSON chứa trường discount_rate: 0.15 vào, Elasticsearch tự động phân tích và tạo một trường kiểu float ở background. Bạn không cần thiết kế Schema trước. (Lưu ý: Dù Elasticsearch tự đoán kiểu được, nhưng trên Production, best practice vẫn là tự định nghĩa Explicit Mapping để tối ưu bộ nhớ và thuật toán tìm kiếm - chúng ta sẽ bàn ở Bài 16).

3. Tính nhất quán (ACID) vs. Tính thời gian thực gần (Near Real-Time)

RDBMS là Source of Truth (Nguồn chân lý): Khi bạn thực hiện một giao dịch thanh toán hoặc trừ tồn kho vé, RDBMS tuân thủ nguyên tắc ACID (Atomicity, Consistency, Isolation, Durability). Nếu một bước trong transaction lỗi, mọi thứ ROLLBACK. Một khi đã COMMIT, dữ liệu lập tức hiển thị với tất cả các luồng đọc khác (Strong Consistency).

Elasticsearch là NRT (Near Real-Time): Elasticsearch tối ưu cho tốc độ đọc. Khi bạn POST một document mới vào Elasticsearch, nó không lập tức có thể tìm kiếm được ngay mili-giây đó. Nó mất khoảng 1 giây (Refresh Interval) để ghi dữ liệu từ bộ đệm Memory Buffer xuống một phân đoạn (Segment) để phục vụ việc search. Vì vậy, tuyệt đối không dùng Elasticsearch làm database chính để xử lý các giao dịch tài chính hay trừ ví tiền.

4. B-Tree Index vs. Inverted Index

Cấu trúc lưu trữ lõi quyết định sức mạnh của công cụ:

  • MySQL dùng B-Tree Index: Tối ưu cho việc tìm kiếm chính xác (Exact match) như id = 123 hoặc tìm khoảng (Range) price BETWEEN 100 AND 200. B-Tree bó tay với các truy vấn Full-text search phức tạp có chấm điểm.

  • Elasticsearch dùng Inverted Index: Hoạt động giống như mục lục ở cuối một cuốn sách. Nó tách cụm từ "Sữa rửa mặt" thành các token độc lập ["sữa", "rửa", "mặt"] và lưu vị trí của từng token này trỏ ngược về Document chứa nó. Nhờ vậy, tìm kiếm văn bản tự do trở nên chớp nhoáng.

Bài học thiết kế hệ thống rút ra: Elasticsearch và RDBMS không phải là đối thủ triệt tiêu nhau, mà là đôi bạn cùng tiến.

Trong một System Architecture chuẩn:

  1. MySQL/PostgreSQL giữ vai trò làm Database chính (Primary Database), lưu trữ Source of Truth, xử lý Transaction (Tạo đơn hàng, Thanh toán, Lưu thông tin User).

  2. Elasticsearch đóng vai trò làm Secondary Data Store. Dữ liệu thay đổi từ MySQL sẽ được đồng bộ (Sync) sang Elasticsearch (thường qua message broker như Kafka hoặc kỹ thuật CDC - Change Data Capture).

  3. Client gửi yêu cầu Search/Filter sản phẩm -> Gọi vào API đọc từ Elasticsearch (Tốc độ mili-giây).

  4. Client gửi yêu cầu Đặt hàng/Thanh toán -> Gọi vào API ghi xuống MySQL (Đảm bảo an toàn 100%).

Hiểu được tư duy này, bạn đã vượt qua rào cản lớn nhất.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí