Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là Technical BA tại một ngân hàng. Một sáng thứ Hai, sếp khối Kinh doanh nhắn: "Anh cần báo cáo doanh số bán bảo hiểm chéo (cross-sell) theo từng chi nhánh, từng sản phẩm, từng tháng trong 3 năm qua, lọc theo phân khúc khách hàng." Bạn quay sang đội kỹ thuật, họ trả lời: "Chạy thẳng trên hệ thống core thì được, nhưng query này sẽ khóa bảng giao dịch, làm chậm toàn bộ giao dịch của khách hàng đang quẹt thẻ ngoài kia. Không được phép."
Đây chính là khoảnh khắc mà mọi tổ chức nhận ra: hệ thống dùng để ghi nhận giao dịch và hệ thống dùng để phân tích báo cáo là hai con vật hoàn toàn khác nhau. Data Warehouse (kho dữ liệu) sinh ra để giải quyết đúng vấn đề này.
Với một Technical BA, đây là chủ đề bạn không thể né. Bạn sẽ là người ngồi giữa: một bên là phòng nghiệp vụ muốn báo cáo "ngay và luôn, đủ chiều, lịch sử dài", một bên là đội data engineer hỏi bạn "vậy chốt lại fact table có grain gì, dimension nào cần lưu lịch sử thay đổi?". Nếu bạn không phân biệt được OLTP với OLAP, không hiểu Kimball khác Inmon ở đâu, bạn sẽ viết spec sai và cả dự án data warehouse trị giá vài tỷ đồng đi chệch hướng. Bài này trang bị cho bạn đúng phần kiến thức đó — không phải để bạn tự build kho dữ liệu, mà để bạn đặt câu hỏi đúng và viết requirement đúng.
Khái niệm cốt lõi
OLTP vs OLAP — gốc rễ của mọi thứ
OLTP (Online Transaction Processing) là hệ thống xử lý giao dịch trực tuyến: hệ thống bán hàng, cổng thanh toán, core banking, ERP. Đặc trưng của nó:
- Tối ưu cho ghi (write) — mỗi giao dịch insert/update vài dòng, hàng nghìn giao dịch mỗi giây.
- Dữ liệu được chuẩn hóa (normalized) đến 3NF để tránh trùng lặp và đảm bảo toàn vẹn. Một đơn hàng tách thành bảng
orders,order_items,customers,products... - Truy vấn điển hình: "Lấy thông tin đơn hàng #12345", "Trừ tồn kho sản phẩm X đi 1". Nhỏ, nhanh, đụng vào ít dòng.
- Chỉ quan tâm trạng thái hiện tại. Khách đổi địa chỉ thì ghi đè, không cần biết địa chỉ cũ.
- Tối ưu cho đọc (read) — quét hàng triệu dòng để tổng hợp (SUM, COUNT, AVG) theo nhiều chiều.
- Dữ liệu thường được phi chuẩn hóa (denormalized) để giảm số phép JOIN, đọc cho nhanh.
- Truy vấn điển hình: "Tổng doanh thu theo vùng theo quý trong 5 năm". Lớn, quét rộng, chấp nhận chạy vài giây đến vài phút.
- Quan tâm cả lịch sử. Cần biết tháng 3 khách thuộc phân khúc nào, dù bây giờ họ đã đổi.
Data Warehouse là gì, và các thành phần
Data Warehouse là kho dữ liệu tập trung, gom dữ liệu từ nhiều nguồn OLTP khác nhau, làm sạch và tổ chức lại để phục vụ phân tích. Bill Inmon — người được gọi là "cha đẻ của data warehouse" — định nghĩa nó có 4 tính chất: subject-oriented (tổ chức theo chủ đề như Khách hàng, Sản phẩm, chứ không theo ứng dụng), integrated (chuẩn hóa dữ liệu từ nhiều nguồn về một chuẩn chung), time-variant (lưu theo thời gian, có chiều lịch sử), và non-volatile (dữ liệu nạp vào thì không sửa/xóa, chỉ thêm).
Hai khái niệm bạn phải nắm để nói chuyện với data engineer:
- Fact table (bảng sự kiện): lưu các con số đo lường được — doanh thu, số lượng, phí. Mỗi dòng là một sự kiện kinh doanh. "Grain" của fact là mức chi tiết của một dòng (ví dụ: một dòng = một dòng sản phẩm trong một hóa đơn).
- Dimension table (bảng chiều): lưu ngữ cảnh để "cắt lát" số liệu — chiều Thời gian, chiều Sản phẩm, chiều Khách hàng, chiều Chi nhánh. Đây là những "theo... " trong yêu cầu báo cáo.
Hai trường phái: Inmon vs Kimball
Đây là trọng tâm của bài. Hai bậc thầy, hai triết lý xây kho dữ liệu khác nhau.
Bill Inmon — cách tiếp cận top-down (CIF — Corporate Information Factory):
- Xây trước một Enterprise Data Warehouse (EDW) tập trung, chuẩn hóa cao (thường 3NF), là "nguồn sự thật duy nhất" cho toàn doanh nghiệp.
- Từ EDW này mới chia ra các data mart (kho dữ liệu chuyên đề nhỏ) cho từng phòng ban: data mart Marketing, data mart Tài chính...
- Ưu điểm: nhất quán toàn doanh nghiệp, ít trùng lặp, dễ quản trị dữ liệu lâu dài, hợp với tổ chức lớn nhiều phòng ban.
- Nhược điểm: tốn thời gian và tiền trước khi ra được giá trị đầu tiên; cần kiến trúc sư dữ liệu giỏi; phòng ban phải chờ lâu.
- Xây trực tiếp các data mart theo mô hình dimensional (star schema) cho từng quy trình kinh doanh (bán hàng, tồn kho...).
- Các data mart được kết nối với nhau qua conformed dimensions — các chiều dùng chung, định nghĩa thống nhất (ví dụ chiều "Khách hàng" giống hệt nhau ở mọi data mart). Tập hợp các mart này tạo thành "data warehouse bus architecture".
- Ưu điểm: ra giá trị nhanh, dễ hiểu với người dùng nghiệp vụ (star schema rất trực quan), query nhanh, chi phí khởi đầu thấp.
- Nhược điểm: nếu không kỷ luật về conformed dimensions, dễ thành các "ốc đảo dữ liệu" mâu thuẫn nhau; khó đảm bảo nhất quán toàn cục khi quy mô lớn.
Slowly Changing Dimension (SCD) — thứ BA hay quên
Khái niệm này nhỏ nhưng cực quan trọng với BA vì nó liên quan trực tiếp đến requirement "lưu lịch sử". Khi một thuộc tính dimension thay đổi (khách hàng chuyển từ phân khúc "Phổ thông" sang "Ưu tiên"), ta xử lý thế nào?
- SCD Type 1: ghi đè, không giữ lịch sử. Đơn giản nhưng mất quá khứ.
- SCD Type 2: tạo dòng mới, đánh dấu
valid_from,valid_to,is_current. Giữ trọn lịch sử. Đây là kiểu hay được yêu cầu nhất. - SCD Type 3: giữ thêm một cột "giá trị trước đó". Chỉ lưu được một bước lịch sử.
Tình huống thực tế
Tình huống 1 — Chuỗi bán lẻ "MinhAnh Mart" chọn Kimball để ra báo cáo nhanh
MinhAnh Mart là chuỗi 40 cửa hàng tạp hóa tại TP.HCM và Bình Dương, doanh thu ~600 tỷ/năm. Ban giám đốc bức xúc vì mỗi cuối tháng phòng kế toán mất 4 ngày ghép Excel từ phần mềm bán hàng (POS) của từng cửa hàng để ra báo cáo doanh thu theo cửa hàng, theo nhóm hàng. Họ thuê một đội tư vấn xây data warehouse.
Là BA của dự án, bạn ghi nhận yêu cầu thực tế: doanh nghiệp cần giá trị trong 2 tháng, không có ngân sách cho một EDW đồ sộ, và người dùng chính là trưởng phòng kinh doanh — không rành kỹ thuật. Đội tư vấn chọn Kimball: dựng ngay một star schema với fact fact_sales (grain = một dòng sản phẩm trên một hóa đơn) và các dimension dim_store, dim_product, dim_date, dim_customer. Sau 6 tuần, dashboard doanh thu theo cửa hàng/nhóm hàng/ngày chạy được, query tổng hợp trả về dưới 3 giây.
Bài học: Khi tổ chức cần kết quả nhanh, quy mô vừa, người dùng nghiệp vụ là chính, và phạm vi rõ ràng (một vài quy trình kinh doanh), Kimball thường thắng. Vai trò BA quan trọng nhất ở đây là chốt grain của fact table — bạn phải hỏi đến cùng: "Một dòng báo cáo chi tiết nhất là gì? Theo hóa đơn hay theo từng sản phẩm trong hóa đơn?" Chốt sai grain là phải làm lại từ đầu.
Tình huống 2 — Ngân hàng "VPCom Bank" và lựa chọn Inmon vì nhiều phòng ban mâu thuẫn
VPCom Bank (giả định) có hơn 10 khối: Bán lẻ, Doanh nghiệp, Thẻ, Rủi ro, Tuân thủ, Marketing. Mỗi khối tự làm báo cáo riêng. Hậu quả: cùng câu hỏi "ngân hàng có bao nhiêu khách hàng đang hoạt động?", khối Bán lẻ trả lời 2,1 triệu, khối Rủi ro nói 1,8 triệu, vì mỗi bên định nghĩa "khách hàng hoạt động" một kiểu. Khi báo cáo lên Ngân hàng Nhà nước, sự lệch số này là rủi ro tuân thủ nghiêm trọng.
Ở đây ban lãnh đạo chọn Inmon: xây một EDW trung tâm, chuẩn hóa, định nghĩa một "nguồn sự thật" cho các khái niệm cốt lõi (khách hàng, tài khoản, giao dịch), rồi mới sinh ra data mart cho từng khối. Dự án kéo dài 14 tháng, tốn kém hơn nhiều so với cách Kimball — nhưng đổi lại, từ đó mọi báo cáo trên toàn ngân hàng dùng chung định nghĩa.
Bài học: Khi tổ chức lớn, nhiều phòng ban, dữ liệu cần nhất quán tuyệt đối và phục vụ tuân thủ pháp lý, cái giá của Inmon (chậm và đắt lúc đầu) là khoản đầu tư đáng giá. Với tư cách BA, đóng góp lớn nhất của bạn không phải kỹ thuật mà là đứng ra hòa giải định nghĩa nghiệp vụ — buộc 10 khối ngồi lại thống nhất "khách hàng hoạt động nghĩa là gì". Đó là công việc của một business analyst đúng nghĩa.
Tình huống 3 — Sàn TMĐT "ShopFast" và bài học về Slowly Changing Dimension
ShopFast (giả định, mô hình kiểu Tiki/Shopee thu nhỏ) làm dashboard phân tích doanh thu theo phân khúc người bán (seller tier: Đồng, Bạc, Vàng). Ban đầu họ dùng SCD Type 1 cho dim_seller — cứ seller lên hạng thì ghi đè. Quý sau, đội phân tích phát hiện một điều kỳ lạ: doanh thu lịch sử của nhóm "Vàng" tăng vọt phi lý ở cả những tháng trước đó. Lý do: nhiều seller mới lên hạng Vàng, và vì ghi đè, toàn bộ doanh thu quá khứ của họ bị gán lại vào hạng Vàng, làm sai lệch mọi báo cáo lịch sử.
BA của ShopFast vào cuộc, viết lại requirement: dim_seller phải dùng SCD Type 2, mỗi lần đổi hạng tạo một bản ghi mới với valid_from/valid_to. Fact doanh thu liên kết tới đúng bản ghi seller tại thời điểm phát sinh. Sau khi nạp lại, báo cáo lịch sử phản ánh đúng hạng seller tại thời điểm đó.
Bài học: Một dòng spec nhỏ — "dimension này có cần lưu lịch sử thay đổi không?" — quyết định độ đúng đắn của toàn bộ báo cáo lịch sử. BA mà bỏ qua câu hỏi SCD sẽ trả giá bằng những con số sai mà không ai phát hiện cho đến khi quá muộn.
Hướng dẫn từng bước
Đây là cách một Technical BA tiếp cận một yêu cầu liên quan đến data warehouse:
- Xác định đây là nhu cầu OLAP hay OLTP. Nếu yêu cầu là "báo cáo, tổng hợp, xu hướng, theo nhiều chiều, lịch sử dài" → OLAP, cần data warehouse. Nếu là "xử lý một giao dịch, cập nhật trạng thái" → OLTP, không đụng tới kho dữ liệu.
- Liệt kê các câu hỏi nghiệp vụ (business questions). Viết ra dạng "Tổng [chỉ số] theo [chiều 1] theo [chiều 2]...". Mỗi chỉ số là ứng viên cho fact (measure); mỗi "theo..." là một dimension. Đây là bước biến yêu cầu mơ hồ thành mô hình dữ liệu.
- Chốt grain của fact table. Hỏi đến tận cùng mức chi tiết nhỏ nhất cần lưu. Grain càng chi tiết càng linh hoạt nhưng càng tốn dung lượng. Đây là quyết định khó đảo ngược, phải làm cùng data engineer.
- Liệt kê dimensions và thuộc tính. Với mỗi dimension, ghi rõ các thuộc tính (attribute) cần để lọc/nhóm. Với mỗi thuộc tính, hỏi: có cần lưu lịch sử thay đổi không? → quyết định SCD Type.
- Xác định conformed dimensions. Nếu có nhiều báo cáo/chủ đề, chỉ ra dimension nào dùng chung (Thời gian, Khách hàng, Sản phẩm) để đảm bảo nhất quán — dù sau này chọn Kimball hay Inmon.
- Đề xuất hướng tiếp cận (Kimball / Inmon / hybrid). Dựa trên: quy mô tổ chức, số phòng ban, mức độ cần nhất quán, ngân sách, thời gian kỳ vọng ra giá trị. Trình bày trade-off rõ ràng cho stakeholder quyết.
- Định nghĩa nguồn dữ liệu và quy tắc làm sạch. Dữ liệu lấy từ hệ thống OLTP nào, key nối ra sao, xử lý dữ liệu thiếu/sai thế nào. (Chi tiết về quy trình nạp dữ liệu sẽ học ở bài ETL/ELT, ở đây bạn chỉ cần chỉ ra nguồn.)
- Định nghĩa từ điển nghiệp vụ (business glossary). Chốt định nghĩa thống nhất cho từng chỉ số và chiều, để tránh thảm họa "mỗi phòng một con số" như VPCom Bank.
Lỗi thường gặp & mẹo
- Chạy báo cáo nặng thẳng trên hệ thống OLTP. Đây là lỗi kinh điển, làm chậm hoặc treo hệ thống giao dịch. Nếu nghe đội kỹ thuật than "query báo cáo khóa bảng giao dịch", đó là tín hiệu cần data warehouse.
- Không chốt grain trước khi thiết kế. Thiết kế fact mà chưa chốt grain là xây nhà không móng. Luôn viết một câu rõ ràng: "Một dòng của fact này đại diện cho ___".
- Quên hỏi về lịch sử (SCD). Như ShopFast, đây là lỗi âm thầm phá hỏng báo cáo lịch sử. Mặc định hãy hỏi mọi dimension: "thuộc tính này có thay đổi theo thời gian không, và nếu có thì báo cáo cần phản ánh giá trị tại thời điểm nào?".
- Trộn lẫn measure vào dimension và ngược lại. Con số cộng được (doanh thu, số lượng) thuộc fact; thuộc tính mô tả để lọc/nhóm thuộc dimension. Mẹo: nếu bạn muốn SUM nó → measure; nếu muốn "group by" theo nó → dimension.
- Tôn sùng một trường phái. Đừng cãi nhau "Kimball mới đúng" hay "phải Inmon". Hãy hỏi: tổ chức cần nhanh hay cần nhất quán toàn cục trước? Bao nhiêu phòng ban? Ngân sách bao nhiêu? Câu trả lời mới dẫn tới lựa chọn.
- Mẹo vàng: Luôn xây trước chiều Thời gian (dim_date) đầy đủ (ngày, tuần, tháng, quý, năm, ngày lễ VN, tuần làm việc). Hầu như mọi báo cáo đều cắt theo thời gian, và một dim_date tốt giúp tiết kiệm vô số công sức về sau.
Bài tập thực hành
Đề bài: Một chuỗi cà phê 25 chi nhánh tại Hà Nội và Đà Nẵng muốn xây báo cáo phân tích. Các câu hỏi nghiệp vụ họ cần trả lời:
- Doanh thu theo chi nhánh, theo nhóm đồ uống, theo từng ngày trong 2 năm qua.
- Số ly bán ra theo khung giờ (sáng/trưa/tối), theo chi nhánh.
- Doanh thu theo hạng thành viên của khách (Thường/Bạc/Vàng) — và phải phản ánh đúng hạng tại thời điểm khách mua, vì khách hay lên/xuống hạng.
- Đề xuất một fact table: tên, grain (một dòng đại diện cho gì?), và liệt kê các measure.
- Liệt kê các dimension cần thiết và 2-3 thuộc tính chính cho mỗi chiều.
- Với dimension khách hàng, chỉ rõ cần SCD Type mấy và giải thích vì sao (dựa trên yêu cầu số 3).
- Bạn sẽ đề xuất tiếp cận Kimball hay Inmon cho dự án quy mô này? Viết 3 câu lý giải dựa trên quy mô, ngân sách và tốc độ ra giá trị.
fact_sales grain "một dòng sản phẩm trên một hóa đơn" với measure doanh thu và số lượng; các dimension dim_date, dim_branch, dim_product, dim_time_of_day, dim_customer; khách hàng dùng SCD Type 2 vì cần phản ánh hạng tại thời điểm mua; và lựa chọn Kimball vì quy mô vừa, ngân sách hạn chế, cần ra dashboard nhanh.Tóm tắt
- OLTP (giao dịch) tối ưu ghi, chuẩn hóa, trạng thái hiện tại; OLAP (phân tích) tối ưu đọc, phi chuẩn hóa, có lịch sử. Đừng bắt OLTP gánh báo cáo nặng.
- Data Warehouse gom dữ liệu nhiều nguồn để phân tích, với hai khối chính: fact table (con số đo lường, có grain) và dimension table (ngữ cảnh để cắt lát). Mô hình phổ biến là star schema.
- Inmon (top-down): xây EDW chuẩn hóa tập trung trước rồi chia data mart — chậm, đắt, nhưng nhất quán toàn doanh nghiệp; hợp tổ chức lớn cần tuân thủ.
- Kimball (bottom-up): xây data mart star schema trước, nối bằng conformed dimensions — nhanh, rẻ, dễ hiểu; hợp khi cần giá trị sớm. Thực tế nhiều nơi dùng hybrid.
- SCD quyết định cách lưu lịch sử dimension. Type 2 (tạo dòng mới với valid_from/valid_to) là kiểu hay được yêu cầu nhất — đừng bao giờ quên hỏi về lịch sử.
- Vai trò BA cốt lõi: dịch câu hỏi nghiệp vụ thành measure + dimension, chốt grain, làm rõ yêu cầu SCD, thống nhất từ điển nghiệp vụ, và trình bày trade-off Kimball/Inmon để stakeholder quyết.