Báo cáo NHNN 6 — Kho dữ liệu phục vụ báo cáo

13 thg 7, 2026 2 lượt xem
#banking
#single-source-of-truth
#regulatory-data-mart
#data-warehouse

Báo cáo NHNN 6 — Kho dữ liệu phục vụ báo cáo

Các bài trước trong series đã đi qua nội dung của báo cáo: tỷ lệ bảo đảm an toàn, báo cáo thống kê tiền tệ, thông tin tín dụng CIC, báo cáo phòng chống rửa tiền. Bài này đổi góc nhìn: dữ liệu để làm ra những con số đó đến từ đâu, và nó phải được lưu trữ, tổ chức thế nào để chịu được sự soi xét của thanh tra.

Câu hỏi tưởng đơn giản mà lại là gốc rễ của gần như mọi sự cố báo cáo: khi cần tính "tổng dư nợ theo ngành cuối tháng 3", ta lấy số ở đâu? Câu trả lời sai — "query thẳng vào core banking" — là nguyên nhân của những đêm đối soát căng thẳng, những con số không tái tạo lại được, và những buổi giải trình mà không ai trong phòng biết chắc số cũ được tính ra sao. Bài này trình bày câu trả lời đúng: một kho dữ liệu chuyên cho báo cáo tuân thủ — thường gọi là regulatory data mart hay reporting layer — được thiết kế riêng cho nhu cầu khắt khe của báo cáo quy định.

Vì sao không query thẳng hệ vận hành

Hệ thống vận hành (OLTP — Online Transaction Processing) như core banking, hệ thẻ, hệ khởi tạo tín dụng được tối ưu cho giao dịch: ghi/đọc từng bản ghi thật nhanh, đảm bảo tính nhất quán tức thời cho từng khách hàng đang thao tác. Chúng không được thiết kế để trả lời câu hỏi tổng hợp toàn hệ thống tại một thời điểm quá khứ. Query báo cáo thẳng vào đó sinh ra một loạt vấn đề, và không cái nào là nhỏ.

1. Dữ liệu vận hành luôn động, báo cáo cần trạng thái đóng băng. Số dư một tài khoản thay đổi theo từng giao dịch. Nếu ta chạy SELECT SUM(balance) lúc 9h và lúc 11h cùng ngày, hai con số khác nhau — cả hai đều "đúng" tại thời điểm chạy, nhưng báo cáo cần một con số: trạng thái cuối ngày làm việc của kỳ báo cáo. Hệ OLTP không lưu lại trạng thái đó; nó chỉ biết hiện tại.

2. Không tái tạo được số cũ. Thanh tra hỏi lại số kỳ tháng 3 khi đang là tháng 6. Query thẳng OLTP bây giờ cho ra trạng thái tháng 6, không phải tháng 3 — dữ liệu đã bị các giao dịch ba tháng qua ghi đè. Ta mất khả năng chứng minh con số đã nộp.

3. Rủi ro hiệu năng và vận hành. Query tổng hợp nặng chạy trên hệ core đang phục vụ giao dịch khách hàng có thể làm chậm cả hệ thống. Không phòng vận hành nào cho phép analyst chạy GROUP BY toàn bảng transactions trên core production giờ cao điểm.

4. Mỗi hệ nguồn một "phương ngữ". Core banking mã hoá loại tài khoản một kiểu, hệ thẻ một kiểu, hệ tín dụng một kiểu. Cùng khái niệm "dư nợ" nhưng định nghĩa và cách tính rải rác, không thống nhất. Query trực tiếp buộc mỗi người viết báo cáo tự đấu nối lại logic — và mỗi người nối một kiểu.

5. Không có dấu vết. OLTP không lưu "con số này được tính lúc nào, từ dữ liệu bản nào, theo công thức gì". Mà đây chính là thứ thanh tra đòi hỏi.

Kết luận: báo cáo tuân thủ cần một lớp dữ liệu tách biệt, được tổ chức theo nhu cầu phân tích (OLAP), ghi lại lịch sử, và là nguồn tính toán duy nhất cho các chỉ tiêu quy định. Đó là regulatory data mart.

Kiến trúc phân lớp

Dữ liệu không đi thẳng từ nguồn tới báo cáo. Nó đi qua các lớp, mỗi lớp có một trách nhiệm rõ ràng. Đây là kiến trúc điển hình cho một ngân hàng cỡ trung như của chúng ta.

Hệ nguồn → Staging/ODS. Bước đầu là trích xuất dữ liệu ra khỏi hệ vận hành, thường bằng batch cuối ngày (EOD extract) hoặc CDC (Change Data Capture) để bắt thay đổi gần thời gian thực. ODS (Operational Data Store) là bản sao gần như nguyên trạng của dữ liệu nguồn — cùng cấu trúc, ít biến đổi. Mục tiêu: gỡ gánh nặng query ra khỏi core, và có một điểm hạ cánh ổn định để làm mọi việc phía sau. ODS là nơi ta chụp lại dữ liệu nguồn tại thời điểm chốt.

Staging/ODS → Chuẩn hoá & tích hợp. Đây là lớp mang giá trị lớn nhất và khó nhất. Nó gồm ba việc:

  • Conform — thống nhất các phương ngữ. Mã ngành từ ba hệ nguồn khác nhau được ánh xạ về một danh mục chuẩn. "Đồng tiền" chuẩn hoá về ISO 4217 (VND, USD...). "Phân loại nợ" quy về một thang thống nhất. Đây là các conformed dimension dùng chung cho mọi báo cáo.
  • Áp business rule — logic tính chỉ tiêu quy định được đặt một chỗ duy nhất ở lớp này, không rải rác trong từng báo cáo. Ví dụ "dư nợ tính vào chỉ tiêu X" được định nghĩa bằng một quy tắc chuẩn, mọi báo cáo cùng dùng.
  • Đối soát (reconciliation) — kiểm tra dữ liệu tích hợp có khớp với nguồn không (tổng số dư của lớp mart phải bằng tổng số dư sổ cái). Chủ đề này sâu tới mức có bài riêng: Đối soát & chất lượng dữ liệu.

Chuẩn hoá → Regulatory Data Mart. Đây là data mart đúng nghĩa: dữ liệu được mô hình hoá theo chỉ tiêu báo cáo. Không phải mô hình theo cách hệ nguồn tổ chức, mà theo cách báo cáo cần đọc. Thường là mô hình chiều (dimensional / star schema): các bảng fact chứa số đo theo chỉ tiêu (dư nợ, số dư huy động, số dư quá hạn) móc vào các dimension (khách hàng, ngành, kỳ hạn, đồng tiền, phân loại nợ, thời gian). Về mô hình hoá chiều, xem lại phần data modeling trong Data warehouse & BigQuerydbt.

Data Mart → Công cụ lập báo cáo. Lớp cuối đọc từ mart để dựng đúng biểu mẫu NHNN, chạy các kiểm tra hợp lệ (validation) trước khi nộp, và phục vụ luôn BI nội bộ để đối chiếu. Vì mọi báo cáo đọc từ cùng một mart, các con số liên báo cáo tự khớp với nhau.

Single source of truth cho chỉ tiêu quy định

Nguyên tắc nền tảng: mỗi chỉ tiêu quy định có đúng một định nghĩa và một nguồn tính toán. Nghe hiển nhiên, nhưng vi phạm nó là căn bệnh phổ biến nhất.

Tình huống điển hình: phòng Quản lý rủi ro tự viết một truy vấn tính "tổng dư nợ" cho báo cáo an toàn vốn; phòng Kế hoạch tài chính viết một truy vấn khác cho báo cáo thống kê; đội CIC lại có logic riêng. Ba con số "tổng dư nợ" ra ba giá trị khác nhau vì mỗi bên loại trừ/gộp một nhóm khoản mục khác nhau. Khi thanh tra hỏi "tại sao dư nợ trên báo cáo A khác báo cáo B", không ai trả lời được.

Regulatory data mart giải bài này bằng cách đưa định nghĩa chỉ tiêu vào chính lớp dữ liệu, không để trong đầu từng người hay trong từng file Excel. Cụ thể:

  • Mỗi chỉ tiêu có một metric definition thành văn: công thức, phạm vi bao gồm/loại trừ, dimension áp dụng, đơn vị.
  • Chỉ tiêu được materialise thành cột/bảng trong mart. Người dùng đọc chỉ tiêu, không tự tính lại.
  • Định nghĩa được quản trị như tài sản: có chủ sở hữu (data owner), có quy trình phê duyệt khi thay đổi. Đây là điểm giao với data governance — xem Governance tổng quan.

Đây chính là ý nghĩa thực chiến của "single source of truth": không phải "một database", mà là một định nghĩa được thống nhất và một chỗ tính.

Versioning & as-of / point-in-time

Đây là yêu cầu làm regulatory data mart khác hẳn data warehouse phân tích thông thường: báo cáo lại một kỳ cũ phải cho ra đúng con số cũ, dù dữ liệu nguồn đã thay đổi. Nói cách khác, ta cần trả lời được câu hỏi "số liệu trông như thế nào tại thời điểm chốt kỳ tháng 3, theo hiểu biết của hệ thống tại lúc đó?".

Có hai kỹ thuật bổ trợ nhau.

Snapshot cuối kỳ. Vào thời điểm chốt (EOD của ngày cuối kỳ), ta đóng băng trạng thái toàn bộ dữ liệu cần cho báo cáo thành một snapshot bất biến, gắn nhãn kỳ báo cáo. Snapshot này không bao giờ bị ghi đè. Muốn báo cáo lại kỳ tháng 3, ta đọc snapshot tháng 3 — bảo đảm ra đúng số đã nộp. Đây là cách đơn giản và mạnh nhất; hầu như mọi báo cáo tuân thủ đều dựa trên snapshot.

Bi-temporal (song thời gian). Kỹ thuật cao hơn, tách bạch hai trục thời gian:

TrụcÝ nghĩaCâu hỏi trả lời
Valid time (thời gian hiệu lực nghiệp vụ)Sự kiện xảy ra trong thực tế lúc nào"Số dư ngày 31/3 là bao nhiêu?"
System/transaction time (thời gian hệ thống ghi nhận)Hệ thống biết điều đó lúc nào"Ngày 5/4 hệ thống hiểu số dư 31/3 ra sao?"

Bi-temporal cho phép phân biệt hai loại "báo cáo lại": (a) tái tạo đúng số đã nộp (đọc theo system time của lúc nộp), và (b) tái tạo số lẽ ra đúng sau khi đã sửa dữ liệu (đọc theo valid time với hiểu biết mới nhất). Sự phân biệt này là tâm điểm của xử lý điều chỉnh hồi tố ở phần dưới.

Về cơ chế lưu lịch sử theo thời gian (SCD Type 2, effective/expiry date), xem thêm trong dbt phần snapshot.

Minh hoạ ý tưởng "as-of" trên sandbox PostgreSQL. Giả sử ta cần tổng số dư theo đồng tiền — con số nền cho nhiều báo cáo. Trên hệ thật, đây phải là snapshot cuối kỳ; ở đây minh hoạ dạng aggregate:

-- ▶ Chạy được
SELECT currency,
       COUNT(*)     AS so_tai_khoan,
       SUM(balance) AS tong_so_du
FROM accounts
GROUP BY currency
ORDER BY tong_so_du DESC;

Câu trên chạy trên trạng thái hiện tại. Điểm mấu chốt của regulatory data mart là: nó không được phép chạy trên trạng thái hiện tại của hệ nguồn — nó chạy trên snapshot đã đóng băng của kỳ báo cáo, để lần chạy nào cũng ra cùng một con số. (Bảng accounts sandbox không có cột thời gian snapshot nên câu trên chỉ minh hoạ phần aggregate; trục as-of là thứ mart thật bổ sung.)

Audit trail & khả năng truy vết

Với báo cáo tuân thủ, con số đúng chưa đủ — phải giải thích được vì sao đúng. Khi thanh tra chất vấn, ngân hàng phải dựng lại toàn bộ đường đi của một con số. Regulatory data mart phải ghi lại:

  • Data lineage — chỉ tiêu này tổng hợp từ bảng/cột nào, qua phép biến đổi nào. Từ ô trên báo cáo, lần ngược được về tới bản ghi giao dịch gốc.
  • Nhật ký nạp (load audit) — mỗi lần nạp dữ liệu: nạp lúc nào, từ nguồn nào, bao nhiêu bản ghi, ai/quy trình nào chạy, kết quả đối soát.
  • Version của business rule — con số kỳ này được tính bằng phiên bản logic nào. Nếu công thức đổi giữa hai kỳ, phải biết mỗi kỳ dùng bản nào.
  • Bất biến (immutability) — snapshot đã chốt không được sửa lặng lẽ. Mọi thay đổi phải để lại dấu vết.

Audit trail không phải tính năng "làm cho vui" — với nhiều loại báo cáo nó là bắt buộc để giải trình. Đây cũng là lý do regulatory data mart thường phải giữ lịch sử nhiều năm, đủ dài theo quy định lưu trữ hồ sơ.

Tách biệt môi trường & kiểm soát thay đổi

Vì output là số nộp cơ quan quản lý, quy trình vận hành phải nghiêm ngặt như phần mềm sản xuất:

  • Tách môi trường DEV / TEST / PROD. Logic báo cáo mới được phát triển và kiểm thử ở DEV/TEST, đối soát kỹ, rồi mới thăng cấp lên PROD. Không ai sửa trực tiếp trên PROD.
  • Kiểm soát thay đổi (change control) — mọi thay đổi định nghĩa chỉ tiêu hay logic tính đều qua review, phê duyệt, có phiên bản. Về CI/CD cho pipeline dữ liệu, tham chiếu quy trình quen thuộc của team.
  • Kiểm thử hồi quy — khi đổi logic, chạy lại trên dữ liệu kỳ cũ để chắc chắn không vô tình đổi số các kỳ đã nộp.
  • Phân quyền — ai được đọc, ai được chốt snapshot, ai được phê duyệt điều chỉnh — tách bạch rõ (segregation of duties).

Xử lý điều chỉnh hồi tố (restatement)

Điều không thể tránh: sau khi đã nộp báo cáo, phát hiện dữ liệu kỳ cũ sai (một khoản vay phân loại nhầm nhóm nợ, một giao dịch hạch toán sai). Phải điều chỉnh hồi tố — restatement. Đây là lúc thiết kế bi-temporal chứng minh giá trị.

Nguyên tắc xử lý:

  1. Không xoá số cũ. Snapshot đã nộp vẫn giữ nguyên (nó là bằng chứng "số đã báo cáo"). Ta tạo phiên bản mới của kỳ đó, không ghi đè bản cũ.
  2. Ghi rõ lý do và phạm vi. Điều chỉnh cái gì, vì sao, ai phê duyệt, ảnh hưởng chỉ tiêu nào.
  3. Phân biệt hai con số. "Số đã nộp" (bản gốc, theo system time cũ) và "số điều chỉnh" (bản mới, theo valid time với dữ liệu đã sửa) cùng tồn tại. Bi-temporal cho phép truy vấn cả hai.
  4. Đánh giá tác động lan truyền. Sửa một chỉ tiêu có thể kéo theo các báo cáo/tỷ lệ khác. Kiểm tra hợp lệ toàn cục lại.
  5. Nộp lại theo đúng quy trình của cơ quan quản lý cho báo cáo điều chỉnh.

Chính vì restatement là chuyện sẽ xảy ra, kiến trúc mart phải được thiết kế để chịu được nó ngay từ đầu — bằng snapshot bất biến, versioning và audit trail. Vá sau khi đã dựng mart theo kiểu ghi đè là gần như bất khả thi.

Use case thực tế

Bối cảnh. Cuối tháng 6/2026, đội báo cáo chốt kỳ và nộp báo cáo có chỉ tiêu "tổng dư nợ theo ngành". Tổng dư nợ toàn hàng báo cáo là 48.500 tỷ đồng, trong đó ngành "Xây dựng" là 6.200 tỷ.

Sự cố. Ngày 20/7, đội tín dụng phát hiện một khách hàng doanh nghiệp dư nợ 300 tỷ bị gán nhầm mã ngành "Thương mại" thay vì "Xây dựng" tại thời điểm chốt tháng 6. Tổng dư nợ toàn hàng đúng (48.500 tỷ), nhưng cơ cấu ngành sai: Xây dựng phải là 6.500 tỷ, Thương mại giảm tương ứng 300 tỷ.

Xử lý nhờ mart được thiết kế đúng:

  1. Tái tạo số đã nộp. Đọc snapshot kỳ 30/6 (bất biến) → xác nhận đúng con số đã nộp: Xây dựng 6.200 tỷ. Có bằng chứng cho thanh tra.
  2. Truy vết nguyên nhân. Theo data lineage, lần ngược con số Xây dựng về tới bản ghi khoản vay của khách hàng đó, thấy mã ngành trong dimension khách hàng bị gán sai từ hệ nguồn.
  3. Tạo phiên bản điều chỉnh. Sửa mã ngành trong lớp chuẩn hoá (theo valid time cuối kỳ 6), sinh snapshot phiên bản 2 của kỳ 30/6. Bản gốc vẫn giữ.
  4. So sánh hai bản. Xây dựng 6.200 → 6.500 tỷ; Thương mại giảm 300 tỷ; tổng 48.500 tỷ không đổi (chỉ dịch chuyển giữa ngành) → hợp lý.
  5. Đánh giá lan truyền & nộp lại. Kiểm tra các chỉ tiêu tập trung theo ngành có bị ảnh hưởng ngưỡng không, chạy lại validation, nộp báo cáo điều chỉnh kèm giải trình.

Nếu query thẳng OLTP: ngày 20/7 chạy lại query sẽ ra ngay số đã sửa (6.500 tỷ) — và ta không còn cách nào chứng minh ngày 30/6 đã nộp 6.200 tỷ, cũng không giải thích được vì sao lệch. Toàn bộ giá trị nằm ở chỗ mart giữ được cả hai trạng thái.

Ghi nhớ

  • Không query thẳng OLTP để làm báo cáo tuân thủ. Dữ liệu vận hành luôn động, không tái tạo được số cũ, rủi ro hiệu năng, và không có dấu vết giải trình.
  • Kiến trúc phân lớp: hệ nguồn → Staging/ODS (bản sao thô) → Chuẩn hoá & tích hợp (conform + business rule + đối soát) → Regulatory Data Mart (mô hình hoá theo chỉ tiêu báo cáo) → công cụ lập báo cáo.
  • Single source of truth nghĩa là một định nghĩa chỉ tiêu + một chỗ tính, đưa định nghĩa vào chính lớp dữ liệu, không rải rác trong từng phòng/từng Excel.
  • Snapshot cuối kỳ bất biến là cơ chế cốt lõi để báo cáo lại kỳ cũ ra đúng số cũ; bi-temporal (valid time vs system time) tách bạch "số đã nộp" với "số đã sửa".
  • Audit trail bắt buộc: data lineage, nhật ký nạp, version business rule, tính bất biến — để giải trình với thanh tra, không phải tính năng tuỳ chọn.
  • Tách môi trường DEV/TEST/PROD + kiểm soát thay đổi + kiểm thử hồi quy trên dữ liệu kỳ cũ để không vô tình đổi số đã nộp.
  • Restatement là chuyện sẽ xảy ra: không xoá số cũ, tạo phiên bản mới, ghi rõ lý do, đánh giá lan truyền, nộp lại. Kiến trúc phải chịu được điều này ngay từ đầu.

Bài viết liên quan

Dòng chảy dữ liệu core -> ODS -> DWH -> BI, mô hình dữ liệu cốt lõi và bộ ví dụ SQL thực hành chạy được.

13 thg 7, 2026 7

Bản chất kinh doanh của ngân hàng: trung gian tài chính, bảng cân đối, NIM và vì sao dữ liệu quan trọng.

13 thg 7, 2026 5

Kiến trúc core banking, CIF, các phân hệ và xử lý online vs batch/EOD.

13 thg 7, 2026 5

Nguyên lý hạch toán kép, Nợ/Có, hệ thống tài khoản và cách mọi giao dịch ngân hàng luôn cân sổ.

13 thg 7, 2026 5