Data Modeling 7 — Quản trị, chất lượng & vận hành mô hình dữ liệu

13 thg 7, 2026 2 lượt xem
#data-quality
#data-engineering
#data-modeling
#lineage
#data-contract
#data-governance

Vì sao mô hình đẹp vẫn có thể vô dụng

Suốt series này ta đã đi từ nền tảng mô hình dữ liệu, qua Kimball chiều/sự kiện, tới kiến trúc hiện đại OBT & metrics layer. Ta đã biết cách vẽ một mô hình chuẩn mực. Nhưng có một sự thật cay đắng: một mô hình dữ liệu hoàn hảo về mặt kỹ thuật vẫn có thể hoàn toàn vô dụng.

Hãy tưởng tượng bạn kế thừa một kho dữ liệu. Có bảng revenue, rev_final, revenue_v2revenue_new — không ai biết dùng bảng nào. Cột amount ở bảng này là VND, ở bảng kia là USD, không ai ghi lại. Sếp hỏi "doanh thu quý này bao nhiêu", ba báo cáo cho ba con số khác nhau. Khi nguồn thượng nguồn lặng lẽ đổi tên một cột, cả pipeline vỡ lúc 2 giờ sáng và không ai biết ai chịu trách nhiệm.

Vấn đề ở đây không phải là mô hình sai. Vấn đề là thiếu quản trị: không nhất quán, không ai hiểu, không ai chịu trách nhiệm, và không có gì canh gác chất lượng. Trong phân tích dữ liệu, tài sản quý nhất không phải là bảng — mà là niềm tin. Người dùng chỉ ra quyết định dựa trên số liệu khi họ tin số liệu đó đúng. Mất niềm tin một lần, họ quay về Excel thủ công, và toàn bộ đầu tư vào data platform trở nên vô nghĩa.

Bài cuối series này khép lại bằng thứ giữ cho mọi mô hình còn sống: quy ước, tài liệu, lineage, chất lượng và quản trị.

Bức tranh tổng thể

Dữ liệu chảy từ trái sang phải qua các tầng biến đổi. Quản trị (catalog, ownership, contract, policy) là lớp bao ngoài cho biết ai sở hữu gì, dùng thế nào, được phép làm gì. Chất lượng (DQ) là các chốt kiểm tra ở mọi tầng. Lineage là tấm bản đồ xuyên suốt để trả lời "số này từ đâu ra" và "đổi cái này thì cái gì vỡ". Bốn thành phần này không tách rời — chúng đan vào nhau tạo thành hệ thống đáng tin cậy.

Quy ước & chuẩn hoá

Nhất quán là nền móng rẻ nhất và hiệu quả nhất của quản trị. Nó không tốn công cụ, chỉ tốn kỷ luật.

Naming convention theo tầng. Cách phổ biến nhất (và là mặc định của dbt) là dùng tiền tố phản ánh vai trò của model:

  • stg_<nguồn>__<thực_thể> — staging: làm sạch 1:1 từ nguồn, ví dụ stg_core__don_hang.
  • int_<mô_tả> — intermediate: bước biến đổi trung gian, không phơi ra cho người dùng.
  • fct_<sự_kiện> — fact/bảng sự kiện, ví dụ fct_don_hang.
  • dim_<thực_thể> — dimension/bảng chiều, ví dụ dim_khach_hang.

Nhìn tên là biết ngay bảng ở đâu trong pipeline và có nên dùng làm nguồn báo cáo hay không.

Quy ước cột. Đặt tên bằng snake_case; khóa chính là <thực_thể>_id; khóa ngoại giữ đúng tên khóa chính bên bảng gốc; boolean bắt đầu bằng is_/has_; thời điểm dùng hậu tố _at (created_at), ngày dùng _date. Đơn vị phải nằm trong tên khi có mơ hồ: amount_vnd, weight_kg. Cùng một khái niệm phải cùng một tên ở mọi nơikhach_hang_id chứ không lúc customer_id, lúc kh_id.

Kiểu dữ liệu nhất quán. Tiền tệ dùng NUMERIC/DECIMAL (không dùng float — sẽ sai số làm tròn); mốc thời gian dùng TIMESTAMPTZ để tránh lẫn lộn múi giờ; định danh dùng cùng một kiểu ở cả hai đầu quan hệ. Một style guide ngắn gọn được cả team đồng ý (và được lint tự động, ví dụ sqlfluff) tiết kiệm hàng trăm giờ tranh cãi và debug về sau.

Tài liệu & data dictionary

Bảng không có tài liệu là bảng không tồn tại — vì không ai dám dùng thứ họ không hiểu.

Data dictionary mô tả từng bảng và từng cột: bảng này là gì, hạt (grain) là gì, cột này nghĩa gì, đơn vị, giá trị hợp lệ, ai sở hữu. Business glossary định nghĩa các thuật ngữ nghiệp vụ và metric ở cấp doanh nghiệp: "khách hàng hoạt động" nghĩa chính xác là gì, "doanh thu thuần" tính ra sao. Khi mọi người dùng chung một định nghĩa, ba báo cáo mới ra cùng một con số.

Cách bền vững nhất là doc-as-code: tài liệu sống cùng code, review cùng PR, không lệch pha. Trong dbt bạn khai mô tả ngay trong file .ymldbt docs generate sinh ra trang web tài liệu kèm lineage graph (xem dbt tests & docs).

# schema.yml — doc-as-code (minh hoạ)
models:
  - name: fct_don_hang
    description: "Sự kiện đơn hàng, grain = 1 dòng / 1 đơn hàng đã xác nhận."
    columns:
      - name: don_hang_id
        description: "Khóa chính, định danh duy nhất mỗi đơn hàng."
      - name: doanh_thu_vnd
        description: "Doanh thu thuần sau chiết khấu, đơn vị VND (NUMERIC)."

Với các thuật ngữ dùng lặp trong nhiều bài, hãy trỏ về trang glossary chung của KB để tránh định nghĩa mỗi nơi một kiểu.

Data lineage

Lineage là bản đồ đường đi của dữ liệu: một cột trong dashboard được tính từ mart nào, mart đó từ model trung gian nào, ngược lên tới cột nào ở bảng nguồn. Tại sao cần?

  • Impact analysis: trước khi đổi/xóa một cột nguồn, biết ngay báo cáo nào sẽ vỡ.
  • Debug (root cause): số trên dashboard sai, lần ngược lineage để tìm điểm gốc gây lỗi thay vì mò từng bảng.
  • Tuân thủ (compliance): chứng minh dữ liệu PII của khách hàng chảy qua đâu, phục vụ GDPR/kiểm toán.

Vẽ tay lineage cho vài bảng thì được, nhưng với hàng trăm model là bất khả thi — nó phải tự động. dbt suy ra lineage từ hàm ref() giữa các model và vẽ DAG cho bạn. Ở phạm vi toàn hệ thống (nhiều công cụ, nhiều engine), chuẩn mở OpenLineage đóng vai trò "ngôn ngữ chung" cho metadata lineage — tách việc thu thập lineage khỏi việc tiêu thụ nó. OpenLineage mô hình hóa quanh ba thực thể: Job (định nghĩa một tiến trình), Run (một lần chạy cụ thể của job), và Dataset (input/output của job), và cho phép mở rộng qua các facet đính kèm metadata như schema, thống kê cột hay số dòng null.

Chất lượng dữ liệu (Data Quality)

Chất lượng không phải cảm tính; nó đo được theo các chiều (dimensions). Khái niệm này được Wang & Strong hình thức hóa từ 1996; ngày nay sáu chiều được dùng phổ biến nhất:

ChiềuCâu hỏiVí dụ kiểm tra
Accuracy (chính xác)Dữ liệu có phản ánh đúng thực tế?Tổng doanh thu khớp với sổ kế toán
Completeness (đầy đủ)Có thiếu giá trị bắt buộc không?khach_hang_id không NULL
Consistency (nhất quán)Có mâu thuẫn giữa các hệ thống?Tổng ở mart = tổng ở nguồn
Timeliness (kịp thời)Dữ liệu có mới đúng lúc cần?Dữ liệu hôm qua đã nạp trước 6h sáng
Uniqueness (duy nhất)Có bản ghi trùng không?don_hang_id là duy nhất
Validity (hợp lệ)Có đúng định dạng/luật nghiệp vụ?trang_thai thuộc tập giá trị cho phép

Kiểm thử tự động biến các chiều trên thành assertion chạy trong pipeline. Trong dbt, bốn test dựng sẵn phủ phần lớn nhu cầu (unique, not_null, relationships, accepted_values); ngoài dbt có Great Expectations và Soda cho rule phong phú hơn. Ví dụ với dbt:

# tests trên model (minh hoạ)
models:
  - name: fct_don_hang
    columns:
      - name: don_hang_id
        tests: [unique, not_null]           # uniqueness + completeness
      - name: khach_hang_id
        tests:
          - relationships:                   # consistency (khóa ngoại)
              to: ref('dim_khach_hang')
              field: khach_hang_id
      - name: trang_thai
        tests:
          - accepted_values:                 # validity
              values: ['moi','xac_nhan','huy','hoan_thanh']

Với các luật nghiệp vụ không có test dựng sẵn, mô tả rule dưới dạng khai báo rồi hiện thực bằng singular test (SQL trả về các dòng vi phạm):

DQ rule (minh hoạ)
- validity : doanh_thu_vnd >= 0
- validity : created_at <= now()            # không có mốc thời gian tương lai
- completeness : tỉ lệ email NOT NULL >= 99%
- timeliness : max(created_at) trong vòng 24h qua

SLA/SLO dữ liệu đưa chất lượng thành cam kết vận hành có thể đo và cảnh báo: ví dụ "mart fct_don_hang được cập nhật xong trước 07:00 mỗi ngày, độ trễ nguồn ≤ 3 giờ, tỉ lệ dòng lỗi ≤ 0.1%". Khi vi phạm SLA phải có cảnh báo tự động tới cả người sở hữu lẫn người tiêu thụ. Với các bất thường khó viết luật cứng (doanh thu tụt đột ngột không rõ lý do), có thể dùng anomaly detection — mô hình học ngưỡng bình thường và báo động khi lệch, một cầu nối tự nhiên sang ML.

Quản trị (Governance)

Quản trị trả lời câu hỏi tổ chức, không chỉ kỹ thuật: ai được biết gì, ai chịu trách nhiệm, dùng ra sao.

Data catalog là "mục lục" của toàn bộ tài sản dữ liệu — nơi người dùng khám phá bảng nào tồn tại, nghĩa là gì, ai dùng, độ tin cậy ra sao. Catalog gom metadata (mô tả, tag, lineage, thống kê, mức độ phổ biến) để biến "kho dữ liệu bí ẩn" thành thứ tìm được và hiểu được.

Ownership & stewardship gán trách nhiệm cụ thể cho từng miền/bảng: owner chịu trách nhiệm cuối về đúng-sai, steward lo chất lượng và ngữ nghĩa hàng ngày. Không có tên người gắn vào bảng thì khi có sự cố không ai nhận, và chất lượng suy giảm không phanh.

Phân loại & bảo mật dữ liệu. Gắn nhãn độ nhạy cảm (public / internal / confidential / PII). Dữ liệu PII (căn cước, số điện thoại, số thẻ) cần masking hoặc mã hóa, và chính sách truy cập theo vai trò (RBAC): ai được xem cột nào. Đây là điểm nối trực tiếp với chủ đề bảo mật dữ liệu — mô hình càng tập trung nhiều dữ liệu nhạy cảm, kiểm soát truy cập càng phải chặt.

Data contracts

Nguyên nhân số một khiến pipeline vỡ là: nguồn thượng nguồn đổi schema mà không báo. Đội backend đổi tên cột status thành state, hoặc đổi kiểu amount từ số sang chuỗi, và mọi thứ hạ nguồn sụp đổ lặng lẽ.

Data contract là hợp đồng chính thức giữa producer (bên tạo dữ liệu) và consumer (bên dùng), định nghĩa rõ schema, ngữ nghĩa, SLA và luật chất lượng của một dataset — thường viết bằng YAML. Điểm mấu chốt: hợp đồng được kiểm thử ngay tại nguồn, nên khi producer định vi phạm (đổi kiểu, bỏ cột, làm rớt chất lượng), CI của họ báo lỗi trước khi dữ liệu độc kịp chảy xuống. Tư duy đằng sau là producer phải coi dữ liệu của mình như một sản phẩm có khách hàng. Đã có chuẩn hóa: Linux Foundation (dự án Bitol) công bố Open Data Contract Standard (ODCS).

Ví dụ một contract tối giản:

# data_contract: don_hang (minh hoạ, phong cách ODCS)
dataset: core.don_hang
owner: team-core-backend
version: "2.1.0"
schema:
  - column: don_hang_id
    type: bigint
    required: true
    unique: true
  - column: doanh_thu_vnd
    type: decimal
    required: true
    constraint: ">= 0"
  - column: trang_thai
    type: string
    allowed: [moi, xac_nhan, huy, hoan_thanh]
sla:
  freshness: "<= 3h"          # độ trễ nguồn tối đa
  availability: "99.5%"
quality:
  - "completeness(don_hang_id) = 100%"
  - "uniqueness(don_hang_id) = 100%"

Khi producer muốn thay đổi phá vỡ (breaking change), họ buộc phải tăng version và phối hợp với consumer — chứ không thể âm thầm làm vỡ pipeline.

Data mesh: quản trị ở quy mô lớn

Khi tổ chức lớn lên, một đội data trung tâm trở thành nút thắt cổ chai cho mọi miền nghiệp vụ. Data mesh là cách tổ chức quản trị phi tập trung, dựa trên bốn nguyên tắc (xem thêm bối cảnh ở kiến trúc hiện đại):

  1. Domain ownership — mỗi miền nghiệp vụ (bán hàng, kho, thanh toán) tự sở hữu và vận hành dữ liệu của mình thay vì đẩy hết cho đội trung tâm.
  2. Data as a product — dữ liệu được tạo ra như một sản phẩm: dễ khám phá, đáng tin, tự mô tả, có địa chỉ và tương tác được, có SLA và người sở hữu rõ ràng.
  3. Self-serve platform — nền tảng chung cho phép các miền tự dựng và phục vụ dữ liệu mà không phải xin đội hạ tầng từng bước.
  4. Federated computational governance — quản trị liên bang: quy tắc chung (naming, bảo mật, PII, tương tác) được tự động hóa và áp dụng thống nhất trên nền tảng, nhưng quyết định cụ thể do miền gần dữ liệu nhất đưa ra.

Data mesh không phải công cụ mà là mô hình tổ chức; nó chỉ hiệu quả khi đã có sẵn kỷ luật về naming, contract, DQ và catalog nói trên.

Vận hành mô hình

Mô hình dữ liệu không đóng băng — nó tiến hóa. Quản lý thay đổi tốt là ranh giới giữa "cải tiến an toàn" và "gây sự cố".

  • Quản lý thay đổi schema: dùng migration có version, tránh đổi tên/xóa cột trực tiếp. Muốn bỏ một cột: thêm cột mới → chuyển consumer sang → deprecate cột cũ → mới xóa (expand-then-contract).
  • Review qua PR: mọi thay đổi model đi qua pull request, được CI chạy test và người khác review — nối với dbt CI/tests. Đây là nơi data contract và DQ tests phát huy: PR vi phạm bị chặn tự động.
  • Tránh breaking changes: coi schema là API công khai. Thêm (additive) thì an toàn; đổi/xóa thì phải phối hợp và tăng version.

Use case thực tế: đưa lớp marts vào chuẩn quản trị

Giả sử team analytics vừa dựng xong lớp marts fct_don_hang + dim_khach_hang + dim_san_pham. Áp toàn bộ khung của bài:

  • Naming: đổi hết về tiền tố fct_/dim_, cột snake_case, khóa *_id, tiền tệ *_vnd, thời điểm *_at — nhìn tên biết ngay tầng và ngữ nghĩa.
  • Tests: unique+not_null cho mọi khóa chính (uniqueness, completeness); relationships từ fct_don_hang.khach_hang_id về dim_khach_hang (consistency); accepted_values cho trang_thai (validity); singular test doanh_thu_vnd >= 0 và freshness ≤ 24h (timeliness).
  • Lineage: dbt tự sinh DAG từ ref(); khi ai đó đề xuất đổi cột nguồn, mở lineage xem đúng những dashboard nào bị ảnh hưởng trước khi merge.
  • Ownership & docs: gán owner cho lớp marts, viết mô tả cột trong schema.yml, publish qua dbt docs. Đăng ký các mart này lên catalog kèm tag độ nhạy cảm; cột PII của dim_khach_hang được masking theo RBAC.
  • Contract: ký data contract với đội backend cho bảng nguồn core.don_hang để họ không âm thầm đổi schema.

Kết quả: khi sếp hỏi doanh thu, chỉ có một con số, ai cũng biết nó từ đâu ra, ai chịu trách nhiệm, và pipeline không vỡ lúc nửa đêm.

Ghi nhớ

  • Tài sản thật của mô hình dữ liệu là niềm tin; quản trị + chất lượng là thứ bảo vệ nó.
  • Nhất quán (naming, kiểu, style guide) là khoản đầu tư rẻ nhất, hiệu quả nhất.
  • Doc-as-code giữ tài liệu không lệch pha với code; glossary chung xóa mơ hồ ngữ nghĩa.
  • Lineage tự động cho phép impact analysis, debug và tuân thủ ở quy mô lớn.
  • Chất lượng đo được theo 6 chiều; biến chúng thành test tự động + SLA + cảnh báo.
  • Data contract chặn breaking change ngay tại nguồn — thay vì để pipeline vỡ.
  • Data mesh phi tập trung hóa quản trị; chỉ chạy được trên nền kỷ luật đã có.

Checklist đưa một mô hình/mart vào production

Checklist production (minh hoạ)
[ ] Naming: đúng tiền tố tầng, cột snake_case, đơn vị rõ trong tên
[ ] Grain của bảng được ghi rõ và có test đảm bảo
[ ] Test đủ 6 chiều: unique/not_null/relationships/accepted_values + rule nghiệp vụ
[ ] SLA/SLO khai báo (freshness, độ trễ, tỉ lệ lỗi) + cảnh báo tự động
[ ] Tài liệu cột đầy đủ trong schema.yml, publish lên docs/catalog
[ ] Owner & steward được gán tên cụ thể
[ ] Phân loại nhạy cảm + masking/RBAC cho cột PII
[ ] Lineage tự sinh, đã chạy impact analysis cho mọi thay đổi
[ ] Data contract với nguồn thượng nguồn (nếu phụ thuộc bên ngoài)
[ ] Thay đổi qua PR, CI chạy test xanh, có người review
[ ] Chiến lược đổi schema an toàn (expand-then-contract, versioning)

Đến đây series Data Modeling & Kho dữ liệu chuyên sâu khép lại: từ nền tảng, dựng mô hình chiều Kimball, tới kiến trúc hiện đại, và cuối cùng là quản trị để giữ tất cả còn đáng tin. Mô hình đẹp là điều kiện cần; quản trị & chất lượng mới là điều kiện đủ để dữ liệu thực sự tạo ra giá trị.


Nguồn tham khảo:

Bài viết liên quan

CSV/JSON/Parquet/Avro, lưu trữ theo hàng vs cột, nén, và OLTP vs OLAP.

13 thg 7, 2026 8

Data Engineering là gì, vai trò trong vòng đời dữ liệu, và bức tranh hệ sinh thái công cụ.

13 thg 7, 2026 5

Vì sao xử lý phân tán, mô hình Spark (RDD/DataFrame), lazy evaluation, shuffle và tối ưu.

13 thg 7, 2026 5

Đảm bảo chất lượng & minh bạch dữ liệu bằng dbt: data tests dựng sẵn (unique, not_null, relationships, accepted_values), singular test, unit test, và tài liệu tự sinh kèm lineage graph.

13 thg 7, 2026 5