Database Storage

Database 302: OLTP hay OLAP?

13 tháng 11, 2020
8 phút đọc
Database 302: OLTP hay OLAP?

Trong thế giới cơ sở dữ liệu, hai khái niệm OLTP và OLAP thường được nhắc đến như hai trụ cột chính với mục đích và đặc tính khác biệt. Bài viết này sẽ giúp bạn hiểu rõ sự khác nhau giữa chúng, cùng với các mô hình và công nghệ liên quan đến OLAP.


OLTP (Xử lý Giao dịch Trực tuyến)#

OLTP (Online Transaction Processing) là hệ thống được thiết kế để xử lý các giao dịch hàng ngày một cách nhanh chóng và chính xác. Ban đầu, cơ sở dữ liệu chủ yếu phục vụ các hoạt động thương mại như bán hàng, đặt hàng, quản lý nhân sự… Dần dần, khái niệm “giao dịch” (transaction) được mở rộng thành một đơn vị công việc logic bao gồm các thao tác INSERT, UPDATE, DELETE hoặc một nhóm các thao tác có tính nguyên tử (ACID).

Đặc điểm của OLTP:

  • Tập trung vào thao tác ghi (write-heavy)

  • Xử lý lượng bản ghi nhỏ, truy vấn thường dùng khóa chính

  • Đảm bảo tính toàn vẹn và nhất quán tức thì

  • Phục vụ người dùng cuối qua ứng dụng web/mobile

Dần dần, người ta bắt đầu khai thác dữ liệu có sẵn với mục đích làm báo cáo, thống kê để đánh giá và cải tiến mô hình kinh doanh,… Nhưng OLTP lại không phù hợp với ngữ cảnh đó: thông thường, việc truy vấn thống kê sẽ cần phải scan trên một khoảng dữ liệu rất rộng. Chưa kể tới việc nó không cần tới toàn bộ dữ liệu thô như OLTP, mà chủ yếu chỉ cần dùng tới một vài cột nhất định để sử dụng các phép gom như sum, average, count,…

Việc này đã dẫn đến 1 mô hình hệ thống mới được ra đời


OLAP (Xử lý Phân tích Trực tuyến)#

OLAP (Online Analytical Processing) ra đời để đáp ứng nhu cầu phân tích dữ liệu lớn, phục vụ báo cáo, thống kê và hỗ trợ ra quyết định. Khác với OLTP, OLAP làm việc với khối lượng dữ liệu khổng lồ, thường từ nhiều nguồn, bảo đảm tính chính xác và tính toàn vẹn của các giao dịch không phải là ưu tiên của chúng. Các hệ thống OLAP có một nhóm người dùng nhỏ hơn so với các hệ thống OLTP, thường là những nhà phân tích hoặc quản lý.

Đặc điểm của OLAP:

  • Tập trung vào thao tác đọc (read-heavy)

  • Truy vấn tổng hợp (SUM, AVG, COUNT…) trên dữ liệu lịch sử

  • Không yêu cầu cập nhật thời gian thực

  • Phục vụ nhà phân tích, quản lý, hệ thống BI


So sánh OLTP và OLAP#

Đặc điểmOLTPOLAP
Mục đíchXử lý giao dịch hàng ngàyPhân tích, báo cáo, dự đoán
Loại truy vấnINSERT, UPDATE, DELETE là chínhSELECT với các hàm tổng hợp
Dữ liệuDữ liệu chi tiết, cập nhật liên tụcDữ liệu lịch sử, tổng hợp
Kích thướcGB → TBTB → PB
Người dùngNgười dùng cuốiNhà phân tích, quản lý
Tốc độPhản hồi nhanh (< 1s)Có thể chấp nhận truy vấn lâu (vài giây → phút)
Mô hình dữ liệuChuẩn hóa (Normalized)Denormalized (Star Schema, Snowflake)

Mô hình Star Schema trong Data Warehouse#

Khi xây dựng Data Warehouse cho OLAP, Star Schema là mô hình phổ biến nhất, bao gồm:

  • Bảng Dimension (Chiều): Mô tả đối tượng phân tích (ví dụ: thời gian, sản phẩm, cửa hàng). Mỗi bảng dimension có thể chứa nhiều thuộc tính và có tính phân cấp.

  • Bảng Fact (Sự kiện): Chứa các số liệu cần phân tích (doanh thu, số lượng) và khóa ngoại tham chiếu đến các bảng dimension.

Ví dụ: Bảng fact fact_sales có khóa ngoại đến dim_date, dim_product, dim_store.

Bảng Fact nằm ở trung tâm của sơ đồ, được nối với các Bảng dimension ở xung quanh, tạo nên hình thù trông khá giống 1 ngôi sao.

Ngoài ra, còn nhiều mô hình khác nữa ví dụ như Snowflake hay Galaxy,… Ở trong bài này mình sẽ không đi sâu vào chi tiết về chúng.


OLAP Cube#

Một khía cạnh cần được quan tâm trong OLAP đó là: hầu hết các câu truy vấn thường liên quan tới các lệnh gom như COUNT, SUM, AVG, MIN, MAX,…

Mô hình dữ liệu thường được sử dụng có tên là OLAP Cube, là thuật ngữ dùng để chỉ dữ liệu có nhiều chiều (dimension) giúp truy vấn tổng hợp nhanh chóng. Với 2 chiều, nó giống một bảng; 3 chiều giống khối Rubik; nhiều hơn gọi là hypercube.

Mình minh họa bằng ví dụ đơn giản nhất là giả thiết rằng bảng Fact của chúng ta chỉ có 2 chiều thôi: date và product. Trong đó: trục dọc là date, và trục ngang là product. Mỗi ô trong bảng sẽ tương ứng với kết quả tính được của product và date tương ứng.

Ta nhận thấy rằng khi chạy gom (reduce) trên 1 dòng bất kỳ thì ta sẽ thu được tổng net_price thu được trong ngày hôm đó, và đồng thời gom trên 1 cột thì ta lại được tổng net_price của sản phẩm trong tất cả các ngày.

Thực tế, bảng Fact thường có nhiều hơn 2 dimension. Nhưng về nguyên tắc thì vẫn là giống nhau: mỗi cell sẽ là giá trị tổng hợp của tất cả các dimension tương ứng.

Kết quả trả về thì có thể chấp nhận không cần chính xác tuyệt đối theo thời gian thực. Như vậy, ta hoàn toàn có thể tính toán sẵn kết quả và lưu lại từ trước, để tránh việc liên tục phải xử lý dữ liệu thô. Một cách để có thể làm được điều đó là sử dụng Materialized View, đã được hỗ trợ sẵn trên hầu hết các cơ sở dữ liệu quan hệ.


Thực hành OLAP Cube với PostgreSQL#

Trong PostgreSQL, từ khóa CUBE được sử dụng trong mệnh đề GROUP BY để tự động tạo ra tất cả các tổ hợp có thể của các cột chỉ định, giúp thực hiện truy vấn tổng hợp đa chiều một cách dễ dàng.

Hiểu về CUBE với ví dụ 3 cột#

Giả sử chúng ta có 3 cột: e1, e2, e3. Khi sử dụng CUBE(e1, e2, e3), PostgreSQL sẽ tạo ra 2³ = 8 tổ hợp nhóm khác nhau. Để dễ hình dung, ta có thể biểu diễn bằng ký hiệu * cho các cột không được nhóm:

CUBE(e1, e2, e3) tạo ra:
1. (e1, e2, e3)  → Nhóm theo cả 3 cột
2. (e1, e2, *)   → Nhóm theo e1, e2; tổng hợp trên mọi giá trị e3
3. (e1, *, e3)   → Nhóm theo e1, e3; tổng hợp trên mọi giá trị e2
4. (e1, *, *)    → Chỉ nhóm theo e1
5. (*, e2, e3)   → Nhóm theo e2, e3; tổng hợp trên mọi giá trị e1
6. (*, e2, *)    → Chỉ nhóm theo e2
7. (*, *, e3)    → Chỉ nhóm theo e3
8. (*, *, *)     → Tổng hợp toàn bộ (không theo cột nào)
💡
Lưu ý: Trong kết quả truy vấn thực tế, các giá trị * sẽ hiển thị là NULL.
Tổng quát hóa
Với n cột trong CUBE, số lượng tổ hợp nhóm là 2ⁿ.

Thực hành với PostgreSQL: Sử dụng CUBE#

Giả sử bảng fact sales của chúng ta chứa dữ liệu như này:

brandsegmentquantity
ABCPremium100
ABCBasic200
XYZPremium100
XYZBasic300

Đây sẽ là câu truy vấn để minh họa cho OLAP Cube 2 chiều (brand, segment):

SELECT
    brand,
    segment,
    SUM (quantity)
FROM
    sales
GROUP BY
    CUBE (brand, segment)
ORDER BY
    brand,
    segment;

Kết quả:

brandsegmentsum
ABCBasic200
ABCPremium100
ABC(NULL)300
XYZBasic300
ZXYZPremium100
XYZ(NULL)400
(NULL)Basic500
(NULL)Premium200
(NULL)(NULL)700

Kết quả bao gồm:

  • Tổng theo từng (brand, segment)

  • Tổng theo từng brand

  • Tổng theo từng segment

  • Tổng toàn cục

Kết hợp với Materialized View#

Để tăng tốc truy vấn, ta dùng Materialized View – lưu kết quả truy vấn lên đĩa để tái sử dụng.

Ví dụ trong PostgreSQL:

CREATE MATERIALIZED VIEW brand_segment_matview AS
SELECT
    brand,
    segment,
    SUM (quantity)
FROM
    sales
GROUP BY
    CUBE (brand, segment)
ORDER BY
    brand,
    segment;

Vì Materialized View không tự động cập nhật lại kết quả khi có thay đổi ở bảng Fact, nên ta sẽ cần refresh định kỳ:

REFRESH MATERIALIZED VIEW brand_segment_matview;

Refresh trong PostgreSQL là Complete Refresh (tức là tính toán toàn bộ lại dữ liệu từ đầu), nên tốt nhất là ta nên chạy nó vào tầm nửa đêm. Một số DB như Oracle hỗ trợ refresh tăng tiến (incremental).


Tổng kết#

  • OLTP phục vụ giao dịch thời gian thực, đảm bảo ACID.

  • OLAP phục vụ phân tích dữ liệu lớn, dùng mô hình Star Schema, Cube.

  • Data Warehouse tách biệt khỏi hệ thống OLTP để tránh ảnh hưởng hiệu năng.

  • Materialized ViewCUBE là công cụ mạnh để tối ưu truy vấn OLAP.

Việc hiểu rõ sự khác biệt giữa OLTP và OLAP giúp thiết kế hệ thống phù hợp, cân bằng giữa hiệu suất giao dịch và khả năng phân tích.

Ở bài tiếp theo, chúng ta sẽ được làm quen tiếp với một loại cơ sở dữ liệu khác chuyên biệt hơn dành cho OLAP: Column-Oriented Storage.

Khám phá thêm