# Syllabus Business Analytics (2)

# PHASE 2 - ANALYTICS ENGINEERING (Ngày 155 – 244)

## Tuần 1-2 - Data Modeling: Kimball (Ngày 155-164)

**Ngày 155: Vì sao cần Data Modeling**

*   Mục tiêu: Hiểu vấn đề mà data modeling giải quyết (dữ liệu raw không dùng trực tiếp được cho BI).
    
*   Lý thuyết: Vấn đề của báo cáo build trực tiếp trên raw table, khái niệm "single source of truth".
    
*   Thực hành: Phân tích 1 raw dataset lộn xộn, liệt kê 5 vấn đề nếu build dashboard trực tiếp trên đó.
    

**Ngày 156: Fact & Dimension Tables**

*   Mục tiêu: Nắm khái niệm nền tảng của Kimball methodology.
    
*   Lý thuyết: Fact table (measurements), dimension table (context), grain của fact table.
    
*   Thực hành: Xác định grain và thiết kế 1 fact table `fact_orders` từ dataset bán hàng.
    

**Ngày 157: Star Schema**

*   Mục tiêu: Thiết kế mô hình star schema hoàn chỉnh.
    
*   Lý thuyết: Cấu trúc star schema, vì sao tối ưu cho query BI.
    
*   Thực hành: Thiết kế star schema đầy đủ (1 fact + 4 dimension) cho dataset e-commerce.
    

**Ngày 158: Snowflake Schema & So sánh**

*   Mục tiêu: Hiểu lựa chọn thay thế và trade-off.
    
*   Lý thuyết: Snowflake schema (dimension chuẩn hóa), so sánh với star schema.
    
*   Thực hành: Chuẩn hóa 1 dimension lớn trong star schema Ngày 157 thành snowflake, đánh giá ưu/nhược.
    

**Ngày 159: Slowly Changing Dimensions (SCD) - Type 1 & 2**

*   Mục tiêu: Xử lý dữ liệu dimension thay đổi theo thời gian.
    
*   Lý thuyết: SCD Type 1 (overwrite) vs Type 2 (lưu lịch sử với effective date).
    
*   Thực hành: Cài đặt SCD Type 2 bằng SQL thủ công cho dimension khách hàng có địa chỉ thay đổi.
    

**Ngày 160: SCD Type 3 & Các biến thể khác**

*   Mục tiêu: Hoàn thiện kiến thức SCD.
    
*   Lý thuyết: SCD Type 3 (lưu giá trị cũ/mới song song), hybrid approaches.
    
*   Thực hành: So sánh 3 loại SCD trên cùng 1 use case, viết nhận xét khi nào dùng loại nào.
    

**Ngày 161: Fact Table Types**

*   Mục tiêu: Phân biệt các loại fact table.
    
*   Lý thuyết: Transactional fact, periodic snapshot fact, accumulating snapshot fact.
    
*   Thực hành: Thiết kế 1 accumulating snapshot fact table cho quy trình đơn hàng (order → ship → deliver).
    

**Ngày 162: Conformed Dimensions**

*   Mục tiêu: Hiểu cách chia sẻ dimension giữa nhiều fact table/business process.
    
*   Lý thuyết: Conformed dimension, bus matrix.
    
*   Thực hành: Vẽ bus matrix cho 1 doanh nghiệp có 3 business process (sales, inventory, marketing).
    

**Ngày 163: Junk Dimension & Degenerate Dimension**

*   Mục tiêu: Xử lý các trường hợp đặc biệt trong modeling.
    
*   Lý thuyết: Junk dimension (gom cờ/flag nhỏ lẻ), degenerate dimension (số hóa đơn nằm trong fact).
    
*   Thực hành: Refactor star schema đã làm để áp dụng junk dimension cho các cờ boolean.
    

**Ngày 164: Dự án Kimball tổng hợp**

*   Mục tiêu: Tổng hợp tuần 1-2.
    
*   Lý thuyết: Checklist review 1 star schema đạt chuẩn Kimball.
    
*   Thực hành: Thiết kế hoàn chỉnh data warehouse Kimball (3 fact + bus matrix) cho 1 công ty bán lẻ đa kênh giả định.
    

## Tuần 3 - Data Vault & Semantic Layer (Ngày 165-174)

**Ngày 165: Giới thiệu Data Vault**

*   Mục tiêu: Hiểu triết lý khác biệt của Data Vault so với Kimball.
    
*   Lý thuyết: Data Vault ưu tiên khả năng audit/mở rộng thay vì tối ưu query trực tiếp.
    
*   Thực hành: So sánh use case nào nên dùng Kimball, use case nào nên dùng Data Vault.
    

**Ngày 166: Hub**

*   Mục tiêu: Hiểu thành phần trung tâm của Data Vault.
    
*   Lý thuyết: Hub lưu business key duy nhất, không lưu attribute mô tả.
    
*   Thực hành: Thiết kế Hub cho customer và product từ dataset đã có.
    

**Ngày 167: Link**

*   Mục tiêu: Mô hình hóa quan hệ giữa các business key.
    
*   Lý thuyết: Link table lưu quan hệ many-to-many giữa các Hub.
    
*   Thực hành: Thiết kế Link giữa Hub customer và Hub product qua bảng orders.
    

**Ngày 168: Satellite**

*   Mục tiêu: Lưu trữ attribute mô tả và lịch sử thay đổi.
    
*   Lý thuyết: Satellite gắn với Hub/Link, lưu lịch sử theo load date.
    
*   Thực hành: Thiết kế Satellite cho Hub customer, mô phỏng việc thêm attribute mới theo thời gian.
    

**Ngày 169: Data Vault hoàn chỉnh & So sánh thực tế**

*   Mục tiêu: Ghép Hub-Link-Satellite thành mô hình hoàn chỉnh.
    
*   Lý thuyết: Data Vault 2.0 overview, ưu/nhược so với Kimball trong thực tế vận hành.
    
*   Thực hành: Vẽ sơ đồ Data Vault hoàn chỉnh cho dataset e-commerce (đã dùng ở Kimball) để so sánh trực tiếp.
    

**Ngày 170: Semantic Layer - Khái niệm**

*   Mục tiêu: Hiểu tầng logic nghiệp vụ nằm giữa warehouse và BI tool.
    
*   Lý thuyết: Vấn đề "mỗi tool định nghĩa metric khác nhau", cách semantic layer giải quyết.
    
*   Thực hành: Liệt kê 1 ví dụ thực tế nơi cùng 1 metric (VD: "Active User") bị định nghĩa khác nhau ở 2 team.
    

**Ngày 171: Metrics Layer trong Modern Data Stack**

*   Mục tiêu: Làm quen công cụ metrics layer hiện đại.
    
*   Lý thuyết: dbt Semantic Layer/MetricFlow, Cube - cách chúng expose metric ra nhiều BI tool.
    
*   Thực hành: Đọc tài liệu MetricFlow, ghi chú kiến trúc và cách định nghĩa 1 metric.
    

**Ngày 172: Business Logic Layer - Best Practices**

*   Mục tiêu: Thiết kế logic nghiệp vụ nhất quán.
    
*   Lý thuyết: Nguyên tắc "define once, use everywhere", version control cho định nghĩa metric.
    
*   Thực hành: Viết tài liệu định nghĩa 5 metric chuẩn hóa (đã làm ở Phase 1) dưới dạng YAML config mẫu.
    

**Ngày 173: Reading Log #5 - Đọc tài liệu Data Vault chính thức**

*   Mục tiêu: Duy trì thói quen reading log với tài liệu kỹ thuật chuyên sâu.
    
*   Lý thuyết: Ghi lại vấn đề tài liệu giải quyết, cấu trúc tổng quan, pattern hay nhất.
    
*   Thực hành: Đọc và viết reading log cho 1 chương tài liệu Data Vault 2.0 hoặc dbt Semantic Layer docs.
    

**Ngày 174: Dự án Data Modeling tổng hợp**

*   Mục tiêu: Tổng hợp toàn bộ tuần 1-3.
    
*   Lý thuyết: So sánh tổng thể Kimball vs Data Vault vs Semantic Layer - khi nào dùng gì.
    
*   Thực hành: Viết tài liệu kiến trúc data modeling đề xuất cho 1 công ty giả định, giải thích lựa chọn.
    

## Tuần 4-5 - dbt Core (Ngày 175-189)

**Ngày 175: Giới thiệu dbt & Cài đặt**

*   Mục tiêu: Hiểu vị trí của dbt trong modern data stack (transform trong ELT).
    
*   Lý thuyết: ELT vs ETL, vai trò dbt là "T".
    
*   Thực hành: Cài đặt dbt Core, kết nối tới 1 warehouse (DuckDB/Postgres/BigQuery sandbox), chạy project mẫu.
    

**Ngày 176: Models cơ bản**

*   Mục tiêu: Viết model dbt đầu tiên.
    
*   Lý thuyết: Model là gì, cách dbt compile SQL + Jinja thành query thật.
    
*   Thực hành: Viết 3 model SQL đơn giản (staging layer) từ raw table.
    

**Ngày 177: Ref & Source**

*   Mục tiêu: Xây dependency graph giữa các model.
    
*   Lý thuyết: `{{ ref() }}` và `{{ source() }}`, cách dbt tự build DAG.
    
*   Thực hành: Kết nối 3 model staging thành 1 model intermediate dùng `ref()`.
    

**Ngày 178: Staging → Intermediate → Mart layers**

*   Mục tiêu: Áp dụng kiến trúc layer chuẩn của dbt.
    
*   Lý thuyết: Vai trò từng layer (staging: 1-1 với source; intermediate: logic trung gian; mart: phục vụ business).
    
*   Thực hành: Refactor project thành đúng 3 layer, đặt tên file theo convention (`stg_`, `int_`, `fct_`/`dim_`).
    

**Ngày 179: Materializations**

*   Mục tiêu: Hiểu cách dbt vật chất hóa model.
    
*   Lý thuyết: View, table, incremental, ephemeral - trade-off của từng loại.
    
*   Thực hành: Áp dụng materialization khác nhau cho từng layer, so sánh thời gian chạy.
    

**Ngày 180: Jinja & Macros cơ bản**

*   Mục tiêu: Viết code SQL tái sử dụng được.
    
*   Lý thuyết: Jinja templating trong dbt, macro là gì.
    
*   Thực hành: Viết 1 macro tái sử dụng (VD: chuẩn hóa định dạng ngày tháng) và dùng ở nhiều model.
    

**Ngày 181: dbt Tests cơ bản**

*   Mục tiêu: Đảm bảo chất lượng dữ liệu ngay trong pipeline.
    
*   Lý thuyết: Generic tests (`unique`, `not_null`, `relationships`, `accepted_values`).
    
*   Thực hành: Thêm test cho toàn bộ model đã viết, chạy `dbt test` và fix lỗi phát hiện.
    

**Ngày 182: Custom (Singular) Tests**

*   Mục tiêu: Viết test cho logic nghiệp vụ riêng.
    
*   Lý thuyết: Singular test là 1 file SQL trả về các dòng "vi phạm".
    
*   Thực hành: Viết 1 custom test kiểm tra doanh thu không được âm.
    

**Ngày 183: dbt Docs**

*   Mục tiêu: Tạo tài liệu tự động cho project.
    
*   Lý thuyết: `dbt docs generate`, `schema.yml` mô tả column/model.
    
*   Thực hành: Viết mô tả đầy đủ cho toàn bộ model, generate docs site và xem lineage graph.
    

**Ngày 184: Sources & Freshness**

*   Mục tiêu: Quản lý dữ liệu nguồn đúng cách.
    
*   Lý thuyết: Khai báo source trong `sources.yml`, kiểm tra freshness.
    
*   Thực hành: Thiết lập `dbt source freshness` cảnh báo khi dữ liệu nguồn quá cũ.
    

**Ngày 185: Seeds & Analyses**

*   Mục tiêu: Xử lý dữ liệu tĩnh và truy vấn ad-hoc trong dbt.
    
*   Lý thuyết: Seeds (CSV nhỏ nạp vào warehouse), analyses (query không materialize).
    
*   Thực hành: Nạp 1 bảng mapping tĩnh (VD: mapping mã khu vực) bằng seed, viết 1 analysis khám phá dữ liệu.
    

**Ngày 186: Project Structure Best Practices**

*   Mục tiêu: Tổ chức project chuẩn dùng trong doanh nghiệp thực tế.
    
*   Lý thuyết: Cấu trúc thư mục chuẩn dbt (theo dbt Labs style guide), naming convention.
    
*   Thực hành: Tái cấu trúc toàn bộ project theo best practices, review lại bằng checklist.
    

**Ngày 187: Dự án dbt Core - Staging layer hoàn chỉnh**

*   Mục tiêu: Áp dụng vào dataset lớn hơn.
    
*   Lý thuyết: Không có lý thuyết mới.
    
*   Thực hành: Xây staging layer đầy đủ cho toàn bộ dataset e-commerce (5+ bảng nguồn).
    

**Ngày 188: Dự án dbt Core - Mart layer hoàn chỉnh**

*   Mục tiêu: Hoàn thiện pipeline transform.
    
*   Lý thuyết: Không có lý thuyết mới.
    
*   Thực hành: Xây mart layer (fact/dim) từ staging layer, đầy đủ test và docs.
    

**Ngày 189: Reading Log #6 + Ôn tập dbt Core**

*   Mục tiêu: Củng cố tuần 4-5.
    
*   Lý thuyết: Reading log cho source code hoặc docs của 1 dbt package phổ biến (VD: `dbt_utils`).
    
*   Thực hành: Viết reading log, ôn tập toàn bộ dbt Core qua checklist tự đánh giá.
    

## Tuần 6-7 - dbt Advanced (Ngày 190-201)

**Ngày 190: Incremental Models (phần 1)**

*   Mục tiêu: Xử lý dữ liệu lớn hiệu quả, không rebuild toàn bộ mỗi lần chạy.
    
*   Lý thuyết: `is_incremental()`, cách dbt chỉ insert/update dữ liệu mới.
    
*   Thực hành: Chuyển 1 model table lớn sang incremental, đo thời gian chạy trước/sau.
    

**Ngày 191: Incremental Models (phần 2) - Strategies**

*   Mục tiêu: Chọn đúng chiến lược incremental.
    
*   Lý thuyết: `merge`, `delete+insert`, `append` strategies - khi nào dùng loại nào.
    
*   Thực hành: Thử nghiệm 2 strategy khác nhau trên cùng 1 model, so sánh kết quả khi có dữ liệu update.
    

**Ngày 192: Snapshots**

*   Mục tiêu: Cài đặt SCD Type 2 tự động bằng dbt.
    
*   Lý thuyết: `dbt snapshot`, `timestamp` vs `check` strategy.
    
*   Thực hành: Thiết lập snapshot cho dimension khách hàng, mô phỏng thay đổi dữ liệu qua nhiều lần chạy.
    

**Ngày 193: Macros nâng cao**

*   Mục tiêu: Viết macro phức tạp, tái sử dụng logic lớn.
    
*   Lý thuyết: Macro với loop, macro trả về SQL động dựa trên metadata.
    
*   Thực hành: Viết macro tự động generate `UNION ALL` cho danh sách bảng động (dùng `run_query`).
    

**Ngày 194: dbt Packages**

*   Mục tiêu: Tận dụng cộng đồng thay vì viết lại từ đầu.
    
*   Lý thuyết: `dbt_utils`, `dbt_expectations`, cách cài đặt package qua `packages.yml`.
    
*   Thực hành: Cài `dbt_utils`, dùng macro `generate_surrogate_key` và `date_spine` trong project.
    

**Ngày 195: Custom Schemas & Environments**

*   Mục tiêu: Quản lý nhiều môi trường (dev/staging/prod).
    
*   Lý thuyết: `generate_schema_name` macro, target trong `profiles.yml`.
    
*   Thực hành: Thiết lập 2 môi trường dev/prod cho project, mỗi môi trường ghi vào schema riêng.
    

**Ngày 196: Variables & Dynamic Configuration**

*   Mục tiêu: Viết model linh hoạt theo tham số truyền vào.
    
*   Lý thuyết: `dbt run --vars`, cách dùng biến trong model.
    
*   Thực hành: Viết 1 model nhận biến ngày bắt đầu/kết thúc để filter dữ liệu động.
    

**Ngày 197: Hooks & Operations**

*   Mục tiêu: Chạy logic tùy chỉnh trước/sau khi build.
    
*   Lý thuyết: `pre-hook`, `post-hook`, `on-run-start`/`on-run-end`.
    
*   Thực hành: Viết post-hook tự động grant quyền SELECT cho 1 role sau khi build model.
    

**Ngày 198: Exposures**

*   Mục tiêu: Khai báo nơi dữ liệu được tiêu thụ (dashboard, ML model).
    
*   Lý thuyết: `exposures.yml`, lợi ích cho lineage và impact analysis.
    
*   Thực hành: Khai báo 2 exposure (1 dashboard Power BI, 1 báo cáo) liên kết tới mart model đã xây.
    

**Ngày 199: Testing nâng cao với dbt\_expectations**

*   Mục tiêu: Viết test phức tạp hơn generic test mặc định.
    
*   Lý thuyết: Package `dbt_expectations` (lấy cảm hứng từ Great Expectations) - các loại test nâng cao.
    
*   Thực hành: Áp dụng test kiểm tra phân phối giá trị (VD: giá trị nằm trong khoảng hợp lý) cho model doanh thu.
    

**Ngày 200: Refactor Case Study - từ Monolith sang Modular**

*   Mục tiêu: Rèn kỹ năng refactor project dbt lớn, lộn xộn.
    
*   Lý thuyết: Dấu hiệu 1 project dbt "code smell" (model quá dài, logic lặp lại).
    
*   Thực hành: Nhận 1 project dbt mẫu viết cẩu thả, refactor thành modular đúng chuẩn.
    

**Ngày 201: Dự án dbt Advanced tổng hợp**

*   Mục tiêu: Tổng hợp tuần 6-7.
    
*   Lý thuyết: Checklist 1 dbt project sẵn sàng production.
    
*   Thực hành: Hoàn thiện toàn bộ project dbt với incremental model, snapshot, package, exposure, test nâng cao.
    

## Tuần 8 - dbt Production: CI/CD, Docs, Lineage (Ngày 202-211)

**Ngày 202: Git Workflow cho dbt**

*   Mục tiêu: Áp dụng version control chuẩn cho project dbt nhóm.
    
*   Lý thuyết: Feature branch workflow, code review cho SQL/dbt.
    
*   Thực hành: Tạo branch, mở pull request cho 1 thay đổi model, tự review theo checklist.
    

**Ngày 203: dbt Cloud vs dbt Core - CI/CD overview**

*   Mục tiêu: Hiểu lựa chọn triển khai dbt.
    
*   Lý thuyết: Khác biệt dbt Cloud và dbt Core self-hosted, job scheduling.
    
*   Thực hành: Đọc tài liệu so sánh, ghi chú ưu/nhược cho từng loại tổ chức.
    

**Ngày 204: CI Pipeline cho dbt (GitHub Actions)**

*   Mục tiêu: Tự động kiểm tra project mỗi khi có thay đổi.
    
*   Lý thuyết: Continuous Integration là gì, slim CI (chỉ build model thay đổi).
    
*   Thực hành: Viết GitHub Actions workflow chạy `dbt build` tự động khi có pull request.
    

**Ngày 205: CD Pipeline - Deploy tự động**

*   Mục tiêu: Tự động deploy sang production sau khi merge.
    
*   Lý thuyết: Continuous Deployment, môi trường staging trước prod.
    
*   Thực hành: Mở rộng workflow Ngày 204 để tự động deploy khi merge vào branch main.
    

**Ngày 206: dbt Docs nâng cao & Hosting**

*   Mục tiêu: Xuất bản tài liệu cho cả team dùng.
    
*   Lý thuyết: Host static docs site (GitHub Pages hoặc dbt Cloud docs).
    
*   Thực hành: Deploy docs site lên GitHub Pages, chia sẻ link.
    

**Ngày 207: Lineage Graph - Đọc và tận dụng**

*   Mục tiêu: Dùng lineage để đánh giá tác động khi thay đổi.
    
*   Lý thuyết: Column-level lineage vs model-level lineage, impact analysis.
    
*   Thực hành: Dùng lineage graph xác định toàn bộ model bị ảnh hưởng nếu đổi 1 cột trong staging.
    

**Ngày 208: Environment Management nâng cao**

*   Mục tiêu: Quản lý config phức tạp hơn cho nhiều team.
    
*   Lý thuyết: `dbt_project.yml` config theo folder, override theo environment.
    
*   Thực hành: Thiết lập config khác nhau (materialization, tags) cho từng nhóm model theo team sở hữu.
    

**Ngày 209: Monitoring dbt Job Runs**

*   Mục tiêu: Theo dõi sức khỏe pipeline sau khi deploy.
    
*   Lý thuyết: Run logs, alerting khi job fail, `run_results.json`.
    
*   Thực hành: Viết script Python đơn giản đọc `run_results.json` và gửi cảnh báo nếu có test fail.
    

**Ngày 210: Code Review Checklist cho dbt**

*   Mục tiêu: Rèn tư duy review code chuyên nghiệp.
    
*   Lý thuyết: Các tiêu chí review 1 PR dbt (naming, test coverage, materialization phù hợp, docs).
    
*   Thực hành: Tự review lại toàn bộ project của mình theo checklist, sửa các điểm chưa đạt.
    

**Ngày 211: Dự án Production tổng hợp**

*   Mục tiêu: Tổng hợp tuần 8.
    
*   Lý thuyết: Checklist "production-ready dbt project".
    
*   Thực hành: Hoàn thiện CI/CD pipeline đầy đủ, docs site, và viết tài liệu vận hành (runbook) ngắn cho project.
    

## Tuần 9-10 - Data Quality (Ngày 212-221)

**Ngày 212: Data Quality Dimensions**

*   Mục tiêu: Có framework đánh giá chất lượng dữ liệu.
    
*   Lý thuyết: Completeness, accuracy, consistency, timeliness, uniqueness, validity.
    
*   Thực hành: Đánh giá 1 dataset theo 6 dimension trên, chấm điểm và liệt kê vấn đề.
    

**Ngày 213: Great Expectations - Giới thiệu**

*   Mục tiêu: Làm quen framework kiểm tra chất lượng dữ liệu chuyên dụng.
    
*   Lý thuyết: Expectation Suite, Data Context, Checkpoint.
    
*   Thực hành: Cài đặt Great Expectations, tạo expectation suite đầu tiên cho 1 bảng dữ liệu.
    

**Ngày 214: Great Expectations - Expectations nâng cao**

*   Mục tiêu: Viết rule kiểm tra phức tạp hơn.
    
*   Lý thuyết: Column-level, table-level, distributional expectations.
    
*   Thực hành: Viết bộ expectation kiểm tra kiểu dữ liệu, khoảng giá trị, và tỷ lệ null cho phép.
    

**Ngày 215: Great Expectations - Data Docs & Validation**

*   Mục tiêu: Trực quan hóa kết quả kiểm tra chất lượng.
    
*   Lý thuyết: Data Docs tự động sinh ra từ kết quả validation.
    
*   Thực hành: Chạy validation, xem báo cáo Data Docs, sửa lỗi dữ liệu phát hiện được.
    

**Ngày 216: Soda Core - Giới thiệu**

*   Mục tiêu: Làm quen công cụ data quality thay thế, cấu hình đơn giản hơn.
    
*   Lý thuyết: Soda Checks Language (SodaCL), so sánh với Great Expectations.
    
*   Thực hành: Viết file check YAML đơn giản cho 1 bảng, chạy `soda scan`.
    

**Ngày 217: Soda - Checks nâng cao**

*   Mục tiêu: Viết check phức tạp và tích hợp cảnh báo.
    
*   Lý thuyết: Anomaly detection check, reference check (so sánh giữa 2 bảng).
    
*   Thực hành: Viết check phát hiện anomaly trong số lượng đơn hàng hàng ngày.
    

**Ngày 218: So sánh Great Expectations vs Soda vs dbt Tests**

*   Mục tiêu: Có quan điểm khi chọn công cụ data quality.
    
*   Lý thuyết: Trade-off về độ phức tạp, khả năng tích hợp CI/CD, learning curve.
    
*   Thực hành: Viết bảng so sánh 3 công cụ, đề xuất công cụ phù hợp cho 2 kịch bản (team nhỏ vs enterprise).
    

**Ngày 219: Data Quality trong Pipeline (Tích hợp CI)**

*   Mục tiêu: Đưa kiểm tra chất lượng vào quy trình tự động.
    
*   Lý thuyết: Vị trí đặt data quality check trong pipeline (trước/sau transform).
    
*   Thực hành: Tích hợp Soda check vào GitHub Actions workflow đã xây ở tuần 8.
    

**Ngày 220: Xử lý khi Data Quality Check Fail**

*   Mục tiêu: Thiết kế quy trình phản ứng khi phát hiện lỗi dữ liệu.
    
*   Lý thuyết: Circuit breaker pattern cho data pipeline, quarantine dữ liệu lỗi.
    
*   Thực hành: Thiết kế logic: nếu check fail thì dừng pipeline và cách ly dữ liệu lỗi thay vì để lan ra dashboard.
    

**Ngày 221: Dự án Data Quality tổng hợp**

*   Mục tiêu: Tổng hợp tuần 9-10.
    
*   Lý thuyết: Checklist "data quality framework" hoàn chỉnh cho 1 warehouse.
    
*   Thực hành: Xây bộ data quality check đầy đủ (dbt tests + Soda) cho toàn bộ mart layer đã có, tích hợp vào CI.
    

## Tuần 11 - Data Contracts *(bổ sung)* (Ngày 222-227)

**Ngày 222: Vì sao cần Data Contracts**

*   Mục tiêu: Hiểu vấn đề "breaking change" giữa team sản xuất và tiêu thụ dữ liệu.
    
*   Lý thuyết: Data contract là gì, khác biệt với data quality check thông thường (contract kiểm tra trước khi dữ liệu vào hệ thống).
    
*   Thực hành: Phân tích 1 tình huống thực tế: team Engineering đổi schema production DB làm vỡ pipeline analytics - xác định contract lẽ ra ngăn được gì.
    

**Ngày 223: Thiết kế Schema Contract**

*   Mục tiêu: Định nghĩa hợp đồng schema rõ ràng.
    
*   Lý thuyết: Cấu trúc 1 data contract (schema, SLA, ownership, versioning).
    
*   Thực hành: Viết 1 data contract YAML cho bảng `orders` (kiểu dữ liệu, ràng buộc, owner, tần suất update).
    

**Ngày 224: Contract Testing**

*   Mục tiêu: Tự động kiểm tra vi phạm contract.
    
*   Lý thuyết: Kiểm tra schema drift, breaking vs non-breaking change.
    
*   Thực hành: Viết script Python đơn giản so sánh schema thực tế với contract đã định nghĩa, cảnh báo nếu lệch.
    

**Ngày 225: Data Contracts trong dbt**

*   Mục tiêu: Áp dụng contract ngay trong công cụ đang dùng.
    
*   Lý thuyết: Tính năng `contract` trong `schema.yml` của dbt (enforce column type).
    
*   Thực hành: Bật `contract: enforced` cho 1 model mart quan trọng, thử đổi kiểu dữ liệu để xem lỗi được bắt thế nào.
    

**Ngày 226: Ownership & Communication Protocol**

*   Mục tiêu: Xử lý khía cạnh tổ chức, không chỉ kỹ thuật.
    
*   Lý thuyết: Vai trò data producer/consumer, quy trình thông báo thay đổi schema.
    
*   Thực hành: Viết quy trình (RFC-style) 3 bước để 1 team engineering thông báo trước khi đổi schema ảnh hưởng tới analytics.
    

**Ngày 227: Dự án Data Contracts tổng hợp**

*   Mục tiêu: Tổng hợp tuần 11.
    
*   Lý thuyết: Checklist data contract sẵn sàng áp dụng thực tế.
    
*   Thực hành: Viết bộ 3 data contract cho 3 bảng nguồn quan trọng nhất trong dự án đang làm.
    

## Tuần 12 - DataOps & Observability *(bổ sung)* (Ngày 228-235)

**Ngày 228: Giới thiệu DataOps**

*   Mục tiêu: Hiểu tư duy vận hành dữ liệu như một sản phẩm (Data as a Product).
    
*   Lý thuyết: DataOps là gì, khác biệt với DevOps truyền thống.
    
*   Thực hành: Đọc 1 case study DataOps thực tế, tóm tắt bằng reading log.
    

**Ngày 229: Data Observability - 5 trụ cột**

*   Mục tiêu: Nắm framework quan sát sức khỏe dữ liệu.
    
*   Lý thuyết: Freshness, Volume, Schema, Distribution, Lineage (theo mô hình Monte Carlo).
    
*   Thực hành: Đánh giá pipeline hiện tại theo 5 trụ cột, xác định trụ cột nào đang thiếu giám sát.
    

**Ngày 230: Anomaly Detection cho Data Pipeline**

*   Mục tiêu: Phát hiện bất thường tự động thay vì chờ người dùng báo lỗi.
    
*   Lý thuyết: Threshold-based vs statistical anomaly detection cho volume/freshness.
    
*   Thực hành: Viết script kiểm tra volume bảng hàng ngày, cảnh báo nếu lệch quá X% so với trung bình 7 ngày.
    

**Ngày 231: SLA cho Data Pipeline**

*   Mục tiêu: Định nghĩa cam kết chất lượng dịch vụ dữ liệu.
    
*   Lý thuyết: SLA (freshness, uptime), SLO, SLI áp dụng cho data pipeline.
    
*   Thực hành: Viết SLA cho pipeline mart layer (VD: "dữ liệu phải sẵn sàng trước 7h sáng hàng ngày").
    

**Ngày 232: Incident Response cho Data**

*   Mục tiêu: Xử lý sự cố dữ liệu chuyên nghiệp.
    
*   Lý thuyết: Quy trình incident response (phát hiện → cách ly → khắc phục → postmortem).
    
*   Thực hành: Viết 1 postmortem giả định cho sự cố "dashboard doanh thu sai số 3 ngày do lỗi upstream".
    

**Ngày 233: Alerting & Notification Design**

*   Mục tiêu: Thiết kế cảnh báo hữu ích, không gây "alert fatigue".
    
*   Lý thuyết: Nguyên tắc alerting tốt (actionable, đúng người nhận, đúng mức độ ưu tiên).
    
*   Thực hành: Thiết kế ma trận alerting (loại lỗi → mức độ nghiêm trọng → kênh thông báo → người nhận).
    

**Ngày 234: Data Catalog Vận hành thực tế**

*   Mục tiêu: Ứng dụng data catalog (đã nhắc ở roadmap gốc) trong bối cảnh DataOps.
    
*   Lý thuyết: Vai trò catalog trong observability - nơi tổng hợp metadata, lineage, ownership.
    
*   Thực hành: Đọc tài liệu DataHub hoặc OpenMetadata, ghi chú cách chúng tích hợp observability.
    

**Ngày 235: Dự án DataOps tổng hợp**

*   Mục tiêu: Tổng hợp tuần 12.
    
*   Lý thuyết: Checklist "data platform có observability trưởng thành".
    
*   Thực hành: Viết tài liệu thiết kế observability đầy đủ (5 trụ cột + SLA + alerting) cho platform đang xây trong Phase 2.
    

## Tuần 13 - Reverse ETL *(bổ sung)* (Ngày 236-241)

**Ngày 236: Reverse ETL là gì**

*   Mục tiêu: Hiểu xu hướng đưa dữ liệu từ warehouse ngược trở lại các công cụ vận hành.
    
*   Lý thuyết: Khác biệt ETL/ELT (đưa dữ liệu vào warehouse) vs Reverse ETL (đưa dữ liệu ra khỏi warehouse).
    
*   Thực hành: Liệt kê 3 use case thực tế cần Reverse ETL (VD: đẩy segment khách hàng vào CRM để sales gọi điện).
    

**Ngày 237: Kiến trúc Reverse ETL**

*   Mục tiêu: Hiểu cách các công cụ như Census/Hightouch hoạt động.
    
*   Lý thuyết: Sync từ warehouse table ra destination (CRM, ad platform, email tool) theo lịch.
    
*   Thực hành: Đọc tài liệu Hightouch hoặc Census, ghi chú kiến trúc sync.
    

**Ngày 238: Xây Model nguồn cho Reverse ETL**

*   Mục tiêu: Chuẩn bị dữ liệu đúng dạng để sync ra hệ thống ngoài.
    
*   Lý thuyết: Yêu cầu khác biệt của model phục vụ Reverse ETL so với model phục vụ BI (cần primary key ổn định, ít cột thừa).
    
*   Thực hành: Xây 1 dbt model mart riêng cho mục đích sync (VD: `mart_customer_segments_for_crm`).
    

**Ngày 239: Thiết lập Sync (thực hành với công cụ miễn phí/demo)**

*   Mục tiêu: Trải nghiệm thực tế quy trình sync.
    
*   Lý thuyết: Field mapping, sync frequency, sync mode (upsert/insert-only).
    
*   Thực hành: Nếu có tài khoản demo Hightouch/Census, thiết lập 1 sync thử; nếu không, mô phỏng bằng script Python gọi API giả lập.
    

**Ngày 240: Rủi ro & Governance của Reverse ETL**

*   Mục tiêu: Hiểu rủi ro khi đẩy dữ liệu sai ra hệ thống vận hành.
    
*   Lý thuyết: Rủi ro (gửi email sai đối tượng, đồng bộ dữ liệu PII không đúng quy định), tầm quan trọng của data quality check trước khi sync.
    
*   Thực hành: Thiết kế bước kiểm tra chất lượng (dbt test) bắt buộc trước khi model được phép sync ra ngoài.
    

**Ngày 241: Dự án Reverse ETL tổng hợp**

*   Mục tiêu: Tổng hợp tuần 13.
    
*   Lý thuyết: Checklist thiết kế 1 luồng Reverse ETL an toàn.
    
*   Thực hành: Viết tài liệu thiết kế đầy đủ 1 use case Reverse ETL (từ mart model → data quality check → sync → destination) cho dự án đang làm.
    

## Tuần 14 - Capstone Phase 2 (Ngày 242-244)

**Ngày 242: Capstone - Thiết kế Warehouse hoàn chỉnh**

*   Mục tiêu: Tổng hợp toàn bộ Phase 2 vào 1 dự án end-to-end.
    
*   Lý thuyết: Không có lý thuyết mới - áp dụng toàn bộ kiến trúc raw → staging → intermediate → mart.
    
*   Thực hành: Thiết kế và xây dựng warehouse hoàn chỉnh cho 1 dataset lớn (có thể dùng lại/mở rộng dataset e-commerce từ Phase 1).
    

**Ngày 243: Capstone - Production-ready hóa**

*   Mục tiêu: Đưa dự án đạt chuẩn production.
    
*   Lý thuyết: Không có lý thuyết mới.
    
*   Thực hành: Thêm đầy đủ CI/CD, data quality check, data contract, docs cho warehouse vừa xây.
    

**Ngày 244: Capstone - Hoàn thiện & Tổng kết Phase 2**

*   Mục tiêu: Kết thúc Phase 2, chuyển giao sang Phase 3.
    
*   Lý thuyết: Nhìn lại toàn bộ hành trình Analytics Engineering - đã sẵn sàng cho Data Engineering (Phase 3) hay chưa.
    
*   Thực hành: Hoàn thiện repo GitHub, viết bài tổng kết Phase 2, cập nhật portfolio, lên kế hoạch Phase 3.
    

# PHASE 3 - DATA ENGINEERING (Ngày 245 – 364)

## Tuần 1 - Docker & Containers (Ngày 245-250)

**Ngày 245: Vì sao cần Container**

*   Mục tiêu: Hiểu vấn đề "works on my machine" mà container giải quyết.
    
*   Lý thuyết: Container vs Virtual Machine, khái niệm image/container/registry.
    
*   Thực hành: Cài Docker, chạy container Postgres đầu tiên bằng `docker run`.
    

**Ngày 246: Dockerfile cơ bản**

*   Mục tiêu: Tự đóng gói ứng dụng thành image.
    
*   Lý thuyết: Cú pháp Dockerfile (`FROM`, `COPY`, `RUN`, `CMD`), layer caching.
    
*   Thực hành: Viết Dockerfile đóng gói script Python ETL đã làm ở Phase 0 thành image chạy được.
    

**Ngày 247: Docker Compose**

*   Mục tiêu: Chạy nhiều service cùng lúc (app + database).
    
*   Lý thuyết: `docker-compose.yml`, network giữa các container.
    
*   Thực hành: Viết docker-compose chạy Postgres + script Python kết nối vào nhau.
    

**Ngày 248: Volumes & Persistence**

*   Mục tiêu: Đảm bảo dữ liệu không mất khi container restart.
    
*   Lý thuyết: Named volumes vs bind mounts.
    
*   Thực hành: Cấu hình volume cho Postgres container, kiểm tra dữ liệu giữ nguyên sau khi restart.
    

**Ngày 249: Chạy dbt + Warehouse local bằng Docker**

*   Mục tiêu: Áp dụng Docker cho chính project đã xây ở Phase 2.
    
*   Lý thuyết: Kết hợp nhiều service (dbt, Postgres/DuckDB) trong 1 compose file.
    
*   Thực hành: Đóng gói project dbt Phase 2 chạy hoàn toàn qua Docker Compose.
    

**Ngày 250: Dự án Docker tổng hợp**

*   Mục tiêu: Tổng hợp tuần 1.
    
*   Lý thuyết: Best practices Dockerfile (multi-stage build, giảm image size).
    
*   Thực hành: Tối ưu lại Dockerfile Ngày 246 bằng multi-stage build, so sánh kích thước image trước/sau.
    

## Tuần 2 - Cloud Fundamentals (Ngày 251-258)

**Ngày 251: Tổng quan Cloud Computing**

*   Mục tiêu: Hiểu mô hình IaaS/PaaS/SaaS và các nhà cung cấp chính.
    
*   Lý thuyết: AWS vs GCP vs Azure - tương quan dịch vụ (S3~GCS~ADLS, Redshift~BigQuery~Synapse).
    
*   Thực hành: Tạo tài khoản free-tier ở 1 cloud provider (khuyến nghị GCP hoặc AWS), khám phá console.
    

**Ngày 252: IAM - Identity and Access Management**

*   Mục tiêu: Hiểu cách cloud quản lý quyền truy cập.
    
*   Lý thuyết: User, role, policy, principle of least privilege.
    
*   Thực hành: Tạo 1 IAM role chỉ có quyền đọc trên 1 bucket cụ thể, test quyền đó.
    

**Ngày 253: Networking cơ bản trên Cloud**

*   Mục tiêu: Hiểu VPC, subnet ở mức đủ dùng cho data engineer.
    
*   Lý thuyết: VPC, public/private subnet, security group/firewall rules.
    
*   Thực hành: Tạo 1 VPC đơn giản với 1 subnet, cấu hình firewall rule cho phép SSH.
    

**Ngày 254: Object Storage trên Cloud**

*   Mục tiêu: Thao tác lưu trữ file trên cloud.
    
*   Lý thuyết: S3/GCS/ADLS - bucket, object, storage class.
    
*   Thực hành: Upload/download file qua CLI (`aws s3` hoặc `gsutil`), thiết lập lifecycle policy tự động xóa file cũ.
    

**Ngày 255: Compute Services cơ bản**

*   Mục tiêu: Hiểu các lựa chọn chạy compute trên cloud.
    
*   Lý thuyết: VM (EC2/Compute Engine) vs serverless (Lambda/Cloud Functions) vs managed container.
    
*   Thực hành: Deploy 1 script Python đơn giản chạy trên serverless function (Lambda hoặc Cloud Function).
    

**Ngày 256: Cost Management & FinOps cơ bản**

*   Mục tiêu: Tránh "hóa đơn cloud bất ngờ" - kỹ năng quan trọng bị bỏ qua ở hầu hết khóa học.
    
*   Lý thuyết: Cost drivers của warehouse (storage, compute, egress), cách đọc billing dashboard.
    
*   Thực hành: Thiết lập billing alert khi chi phí vượt ngưỡng, phân tích 1 bill mẫu để tìm chi phí bất thường.
    

**Ngày 257: Secrets Management**

*   Mục tiêu: Quản lý credential an toàn, không hardcode.
    
*   Lý thuyết: Secret Manager, biến môi trường an toàn trong CI/CD.
    
*   Thực hành: Lưu 1 API key vào Secret Manager, đọc secret đó từ script Python.
    

**Ngày 258: Dự án Cloud Fundamentals tổng hợp**

*   Mục tiêu: Tổng hợp tuần 2.
    
*   Lý thuyết: Checklist bảo mật cơ bản khi setup 1 data platform trên cloud.
    
*   Thực hành: Setup hoàn chỉnh: 1 bucket + 1 IAM role giới hạn quyền + 1 billing alert cho project sắp xây ở các tuần tiếp theo.
    

## Tuần 3-5 - Data Warehousing (Ngày 259-274)

### Snowflake (Ngày 259-262)

**Ngày 259: Snowflake - Kiến trúc**

*   Mục tiêu: Hiểu kiến trúc tách biệt storage/compute độc đáo của Snowflake.
    
*   Lý thuyết: Multi-cluster architecture, virtual warehouse, tại sao scale độc lập storage/compute.
    
*   Thực hành: Tạo tài khoản Snowflake trial, tạo warehouse, database, load 1 dataset mẫu.
    

**Ngày 260: Snowflake - Query & Performance**

*   Mục tiêu: Viết truy vấn hiệu quả trên Snowflake.
    
*   Lý thuyết: Query profile, caching (result cache, warehouse cache).
    
*   Thực hành: Chạy cùng 1 truy vấn 2 lần, quan sát result cache tăng tốc thế nào.
    

**Ngày 261: Snowflake - Scaling & Cost Control**

*   Mục tiêu: Cân bằng hiệu năng và chi phí.
    
*   Lý thuyết: Warehouse sizing, auto-suspend/auto-resume, multi-cluster scaling.
    
*   Thực hành: Cấu hình auto-suspend cho warehouse, thử nghiệm resize warehouse và đo tác động tốc độ.
    

**Ngày 262: Snowflake - Time Travel & Zero-Copy Cloning**

*   Mục tiêu: Tận dụng tính năng độc quyền của Snowflake.
    
*   Lý thuyết: Time travel (truy vấn dữ liệu quá khứ), zero-copy clone.
    
*   Thực hành: Clone 1 database để thử nghiệm mà không tốn thêm storage, khôi phục 1 bảng bị xóa nhầm bằng time travel.
    

### BigQuery (Ngày 263-266)

**Ngày 263: BigQuery - Kiến trúc Serverless**

*   Mục tiêu: Hiểu mô hình serverless hoàn toàn của BigQuery.
    
*   Lý thuyết: Không cần quản lý cluster, pricing theo bytes scanned hoặc slot.
    
*   Thực hành: Chạy truy vấn trên public dataset của BigQuery (VD: `bigquery-public-data`).
    

**Ngày 264: BigQuery - Partitioning & Clustering**

*   Mục tiêu: Tối ưu chi phí và tốc độ truy vấn.
    
*   Lý thuyết: Partition theo ngày, clustering theo cột, tác động đến bytes scanned.
    
*   Thực hành: Tạo bảng partition + cluster, so sánh bytes scanned với bảng không tối ưu.
    

**Ngày 265: BigQuery - Pricing Models**

*   Mục tiêu: Hiểu và kiểm soát chi phí.
    
*   Lý thuyết: On-demand pricing vs flat-rate (slot reservation).
    
*   Thực hành: Tính chi phí ước tính cho 1 truy vấn trước khi chạy bằng dry-run.
    

**Ngày 266: BigQuery ML cơ bản (mở rộng)**

*   Mục tiêu: Thấy khả năng chạy ML ngay trong warehouse.
    
*   Lý thuyết: `CREATE MODEL` trong BigQuery ML, use case phù hợp.
    
*   Thực hành: Train 1 model linear regression đơn giản bằng BigQuery ML trên dataset công khai.
    

### Redshift & ClickHouse (Ngày 267-274)

**Ngày 267: Redshift - Kiến trúc**

*   Mục tiêu: Hiểu warehouse dạng cluster truyền thống của AWS.
    
*   Lý thuyết: Leader node, compute node, distribution style (KEY/ALL/EVEN).
    
*   Thực hành: Đọc tài liệu kiến trúc Redshift, so sánh với Snowflake (đã học) - ghi chú khác biệt.
    

**Ngày 268: Redshift - Distribution & Sort Keys**

*   Mục tiêu: Tối ưu truy vấn qua thiết kế bảng đúng.
    
*   Lý thuyết: Distribution key giảm data shuffling, sort key tăng tốc filter.
    
*   Thực hành: Thiết kế distribution/sort key phù hợp cho 1 bảng fact lớn (dựa trên pattern truy vấn thường gặp).
    

**Ngày 269: Redshift Spectrum**

*   Mục tiêu: Hiểu cách Redshift truy vấn trực tiếp data lake.
    
*   Lý thuyết: Redshift Spectrum - query S3 mà không cần load vào warehouse.
    
*   Thực hành: Đọc tài liệu, mô phỏng use case query external table trên S3.
    

**Ngày 270: ClickHouse - Giới thiệu**

*   Mục tiêu: Làm quen OLAP engine tốc độ cao chuyên biệt.
    
*   Lý thuyết: Column-oriented storage, use case (real-time analytics, log analytics).
    
*   Thực hành: Cài ClickHouse local (Docker), load 1 dataset và chạy truy vấn aggregation.
    

**Ngày 271: ClickHouse - MergeTree Engine**

*   Mục tiêu: Hiểu engine lưu trữ đặc trưng của ClickHouse.
    
*   Lý thuyết: MergeTree, primary key khác biệt so với RDBMS truyền thống, partitioning.
    
*   Thực hành: Tạo bảng MergeTree với partition theo tháng, so sánh tốc độ query với bảng không partition.
    

**Ngày 272: ClickHouse - Khi nào chọn ClickHouse**

*   Mục tiêu: Có tiêu chí lựa chọn công cụ warehouse phù hợp.
    
*   Lý thuyết: So sánh ClickHouse vs Snowflake/BigQuery về latency, use case real-time dashboard.
    
*   Thực hành: Viết bảng so sánh 4 warehouse đã học (Snowflake/BigQuery/Redshift/ClickHouse) theo: pricing model, use case tốt nhất, độ phức tạp vận hành.
    

**Ngày 273: Reading Log #7 - Đọc tài liệu kiến trúc 1 warehouse**

*   Mục tiêu: Duy trì thói quen reading log.
    
*   Lý thuyết: Reading log cho whitepaper kiến trúc (VD: Snowflake elastic warehouse paper hoặc ClickHouse docs).
    
*   Thực hành: Viết reading log chi tiết cho 1 whitepaper/tài liệu kiến trúc đã đọc.
    

**Ngày 274: Dự án Data Warehousing tổng hợp**

*   Mục tiêu: Tổng hợp tuần 3-5.
    
*   Lý thuyết: Framework ra quyết định chọn warehouse cho 1 tổ chức cụ thể.
    
*   Thực hành: Viết đề xuất kiến trúc warehouse cho 3 kịch bản công ty khác nhau (startup ít dữ liệu, công ty real-time analytics, tập đoàn lớn multi-cloud).
    

## Tuần 6-7 - Storage Internals (Ngày 275-282)

**Ngày 275: Row-based vs Column-based Storage**

*   Mục tiêu: Hiểu nền tảng vì sao warehouse phân tích dùng columnar storage.
    
*   Lý thuyết: OLTP (row-based) vs OLAP (columnar), lợi ích nén và scan theo cột.
    
*   Thực hành: Mô phỏng bằng tay: tính lượng I/O cần đọc cho 1 truy vấn aggregate trên row-store vs column-store.
    

**Ngày 276: Compression Techniques**

*   Mục tiêu: Hiểu vì sao columnar storage nén hiệu quả hơn.
    
*   Lý thuyết: Run-length encoding, dictionary encoding, delta encoding.
    
*   Thực hành: Nén thử 1 cột dữ liệu categorical bằng dictionary encoding thủ công bằng Python, đo tỷ lệ nén.
    

**Ngày 277: Parquet - Cấu trúc File**

*   Mục tiêu: Hiểu định dạng file phổ biến nhất trong data lake hiện đại.
    
*   Lý thuyết: Row group, column chunk, page, metadata footer.
    
*   Thực hành: Đọc metadata của 1 file Parquet bằng `pyarrow`, in ra schema và statistics.
    

**Ngày 278: Parquet - Thực hành sâu**

*   Mục tiêu: Thao tác Parquet hiệu quả trong Python.
    
*   Lý thuyết: Predicate pushdown, column pruning.
    
*   Thực hành: So sánh tốc độ đọc 1 cột từ file Parquet vs CSV cùng dataset lớn.
    

**Ngày 279: ORC**

*   Mục tiêu: Hiểu định dạng thay thế phổ biến trong hệ sinh thái Hadoop/Hive.
    
*   Lý thuyết: Cấu trúc ORC, so sánh với Parquet.
    
*   Thực hành: Đọc tài liệu so sánh Parquet vs ORC, ghi chú khi nào dùng loại nào.
    

**Ngày 280: Apache Arrow**

*   Mục tiêu: Hiểu định dạng in-memory chuẩn hóa hiện đại.
    
*   Lý thuyết: Arrow là gì, vì sao giúp trao đổi dữ liệu giữa các hệ thống (Pandas, Spark, DuckDB) không cần serialize lại.
    
*   Thực hành: Chuyển đổi giữa Pandas DataFrame và Arrow Table bằng `pyarrow`, đo tốc độ so với chuyển qua CSV trung gian.
    

**Ngày 281: So sánh tổng hợp Storage Formats**

*   Mục tiêu: Có quan điểm rõ ràng khi chọn định dạng lưu trữ.
    
*   Lý thuyết: Bảng so sánh CSV/JSON/Parquet/ORC/Arrow theo: nén, tốc độ đọc, khả năng schema evolution.
    
*   Thực hành: Viết benchmark nhỏ: đọc cùng dataset ở 3 định dạng khác nhau, so sánh thời gian và dung lượng.
    

**Ngày 282: Dự án Storage Internals tổng hợp**

*   Mục tiêu: Tổng hợp tuần 6-7.
    
*   Lý thuyết: Checklist chọn storage format cho 1 data lake mới.
    
*   Thực hành: Viết đề xuất định dạng lưu trữ cho từng layer (raw/staging/mart) của data lake sắp xây.
    

## Tuần 8 - Data Lake (Ngày 283-288)

**Ngày 283: Data Lake - Khái niệm & So sánh với Warehouse**

*   Mục tiêu: Hiểu khác biệt triết lý data lake vs data warehouse.
    
*   Lý thuyết: Schema-on-read vs schema-on-write, ưu/nhược từng mô hình.
    
*   Thực hành: Vẽ sơ đồ so sánh data lake vs warehouse, liệt kê use case phù hợp mỗi loại.
    

**Ngày 284: S3 - Thực hành sâu**

*   Mục tiêu: Thành thạo thao tác S3 cho mục đích data lake.
    
*   Lý thuyết: Bucket structure, prefix design cho hiệu năng liệt kê file.
    
*   Thực hành: Thiết kế cấu trúc thư mục S3 chuẩn (`raw/`, `staging/`, `mart/` theo ngày) và upload dữ liệu mẫu.
    

**Ngày 285: GCS & ADLS**

*   Mục tiêu: Nắm sự tương đồng/khác biệt giữa các object storage.
    
*   Lý thuyết: So sánh S3 vs GCS vs ADLS về API, pricing, tích hợp.
    
*   Thực hành: Thực hiện lại thao tác upload/liệt kê file Ngày 284 nhưng trên GCS (nếu có tài khoản), so sánh trải nghiệm.
    

**Ngày 286: Data Lake Zones**

*   Mục tiêu: Thiết kế kiến trúc phân lớp cho data lake.
    
*   Lý thuyết: Bronze/Silver/Gold zone (hoặc Raw/Cleaned/Curated).
    
*   Thực hành: Thiết kế zone architecture cho dataset đang dùng xuyên suốt Phase 3.
    

**Ngày 287: Data Lakehouse - Khái niệm**

*   Mục tiêu: Hiểu xu hướng hội tụ giữa lake và warehouse.
    
*   Lý thuyết: Lakehouse là gì, vì sao table format (sẽ học tuần sau) là chìa khóa.
    
*   Thực hành: Đọc bài viết/paper giới thiệu Lakehouse (Databricks), tóm tắt luận điểm chính bằng reading log.
    

**Ngày 288: Dự án Data Lake tổng hợp**

*   Mục tiêu: Tổng hợp tuần 8.
    
*   Lý thuyết: Checklist thiết kế data lake zone chuẩn.
    
*   Thực hành: Setup hoàn chỉnh cấu trúc S3/GCS 3 zone cho dataset dự án, upload dữ liệu raw vào Bronze zone.
    

## Tuần 9-10 - Table Formats (Ngày 289-300)

**Ngày 289: Vấn đề của Data Lake "thuần" (không table format)**

*   Mục tiêu: Hiểu động lực ra đời của table format hiện đại.
    
*   Lý thuyết: Vấn đề: không ACID, không schema evolution an toàn, khó update/delete trên file.
    
*   Thực hành: Mô phỏng vấn đề: thử "update" 1 dòng dữ liệu trong file Parquet thuần, thấy phải viết lại toàn bộ file.
    

**Ngày 290: Apache Iceberg - Kiến trúc**

*   Mục tiêu: Hiểu table format phổ biến nhất hiện nay.
    
*   Lý thuyết: Snapshot, manifest file, metadata layer của Iceberg.
    
*   Thực hành: Đọc tài liệu kiến trúc Iceberg, vẽ sơ đồ 3 lớp (catalog → metadata → data files).
    

**Ngày 291: Apache Iceberg - Thực hành**

*   Mục tiêu: Thao tác Iceberg table thực tế.
    
*   Lý thuyết: Tạo table, insert, time travel trong Iceberg.
    
*   Thực hành: Dùng PyIceberg hoặc Spark tạo 1 Iceberg table, insert dữ liệu, query snapshot cũ.
    

**Ngày 292: Apache Iceberg - Schema Evolution**

*   Mục tiêu: Hiểu tính năng cốt lõi giải quyết vấn đề Ngày 289.
    
*   Lý thuyết: Thêm/xóa/đổi tên cột an toàn mà không cần rewrite toàn bộ dữ liệu.
    
*   Thực hành: Thử thêm 1 cột mới vào Iceberg table đã tạo, kiểm tra dữ liệu cũ vẫn đọc được bình thường.
    

**Ngày 293: Delta Lake - Kiến trúc**

*   Mục tiêu: Hiểu table format của hệ sinh thái Databricks.
    
*   Lý thuyết: Transaction log (`_delta_log`), ACID transactions.
    
*   Thực hành: Tạo 1 Delta table bằng PySpark local, xem transaction log.
    

**Ngày 294: Delta Lake - Time Travel & MERGE**

*   Mục tiêu: Thao tác update/upsert trên Delta Lake.
    
*   Lý thuyết: `MERGE INTO` cho upsert, time travel bằng version number.
    
*   Thực hành: Thực hiện upsert dữ liệu vào Delta table bằng `MERGE`, sau đó query lại version cũ.
    

**Ngày 295: Apache Hudi - Kiến trúc**

*   Mục tiêu: Hiểu table format thứ 3, mạnh về incremental processing.
    
*   Lý thuyết: Copy-on-Write vs Merge-on-Read trong Hudi.
    
*   Thực hành: Đọc tài liệu Hudi, so sánh 2 write mode về trade-off write/read latency.
    

**Ngày 296: So sánh Iceberg vs Delta Lake vs Hudi**

*   Mục tiêu: Có quan điểm chọn table format cho dự án thực tế.
    
*   Lý thuyết: So sánh theo: hệ sinh thái hỗ trợ, tốc độ, độ trưởng thành cộng đồng.
    
*   Thực hành: Viết bảng so sánh 3 table format, đề xuất lựa chọn cho dự án capstone sắp làm.
    

**Ngày 297: Catalog cho Table Format**

*   Mục tiêu: Hiểu vai trò catalog (nơi track table nào tồn tại, ở đâu).
    
*   Lý thuyết: Hive Metastore, AWS Glue Catalog, Iceberg REST Catalog.
    
*   Thực hành: Setup 1 catalog đơn giản (VD: SQLite-based Iceberg catalog) cho project local.
    

**Ngày 298: Partitioning trong Table Format hiện đại**

*   Mục tiêu: Hiểu partitioning "thông minh" của Iceberg so với Hive truyền thống.
    
*   Lý thuyết: Hidden partitioning của Iceberg - không cần biết cấu trúc partition khi query.
    
*   Thực hành: Thiết lập hidden partitioning theo ngày cho Iceberg table, viết truy vấn không cần chỉ định partition thủ công.
    

**Ngày 299: Compaction & Maintenance**

*   Mục tiêu: Hiểu vận hành thực tế của table format (không chỉ lý thuyết).
    
*   Lý thuyết: Small file problem, compaction, vacuum/expire snapshots.
    
*   Thực hành: Chạy lệnh compaction trên Iceberg/Delta table đã tạo nhiều file nhỏ, so sánh hiệu năng trước/sau.
    

**Ngày 300: Dự án Table Format tổng hợp**

*   Mục tiêu: Tổng hợp tuần 9-10.
    
*   Lý thuyết: Checklist "table format production-ready".
    
*   Thực hành: Xây 1 Iceberg table hoàn chỉnh cho Gold zone của data lake (từ Ngày 286-288), có catalog, partitioning, và lịch compaction.
    

## Tuần 11-13 - Batch Processing: Apache Spark (Ngày 301-320)

**Ngày 301: Spark - Kiến trúc tổng quan**

*   Mục tiêu: Hiểu mô hình phân tán của Spark.
    
*   Lý thuyết: Driver, executor, cluster manager.
    
*   Thực hành: Cài PySpark local, chạy job "Hello World" đếm từ trong 1 file text.
    

**Ngày 302: RDD - Nền tảng thấp nhất**

*   Mục tiêu: Hiểu abstraction gốc của Spark (dù ít dùng trực tiếp ngày nay).
    
*   Lý thuyết: RDD là gì, transformation vs action, lazy evaluation.
    
*   Thực hành: Viết 3 phép biến đổi RDD cơ bản (`map`, `filter`, `reduceByKey`).
    

**Ngày 303: DataFrame API**

*   Mục tiêu: Làm quen API chính dùng trong thực tế.
    
*   Lý thuyết: DataFrame vs RDD, ưu điểm về optimizer.
    
*   Thực hành: Chuyển đổi 3 phép biến đổi RDD Ngày 302 sang DataFrame API.
    

**Ngày 304: DataFrame - Transformations nâng cao**

*   Mục tiêu: Thao tác dữ liệu phức tạp bằng Spark.
    
*   Lý thuyết: `groupBy`, `agg`, `join`, `window` functions trong Spark.
    
*   Thực hành: Viết pipeline Spark tính doanh thu theo tháng và running total bằng window function.
    

**Ngày 305: Spark SQL**

*   Mục tiêu: Dùng SQL thuần trong Spark.
    
*   Lý thuyết: Đăng ký temp view, chạy SQL trực tiếp trên DataFrame.
    
*   Thực hành: Viết lại pipeline Ngày 304 hoàn toàn bằng Spark SQL.
    

**Ngày 306: Catalyst Optimizer**

*   Mục tiêu: Hiểu vì sao Spark SQL nhanh.
    
*   Lý thuyết: Logical plan → optimized logical plan → physical plan, predicate pushdown.
    
*   Thực hành: Dùng `.explain()` xem execution plan của 1 truy vấn, xác định optimization Catalyst đã áp dụng.
    

**Ngày 307: Partitioning trong Spark**

*   Mục tiêu: Hiểu cách Spark chia dữ liệu để xử lý song song.
    
*   Lý thuyết: `repartition` vs `coalesce`, ảnh hưởng đến performance.
    
*   Thực hành: So sánh thời gian chạy job với số partition khác nhau trên cùng dataset.
    

**Ngày 308: Shuffle - Cơ chế & Chi phí**

*   Mục tiêu: Hiểu thao tác tốn kém nhất trong Spark.
    
*   Lý thuyết: Khi nào shuffle xảy ra (`groupBy`, `join`, `repartition`), chi phí I/O + network.
    
*   Thực hành: Xác định và giảm số lần shuffle trong 1 pipeline đã viết bằng cách reorder operations.
    

**Ngày 309: Broadcast Join**

*   Mục tiêu: Tối ưu join khi 1 bảng nhỏ.
    
*   Lý thuyết: Broadcast join tránh shuffle khi join bảng lớn với bảng nhỏ.
    
*   Thực hành: So sánh thời gian chạy join thường vs broadcast join giữa fact table lớn và dimension nhỏ.
    

**Ngày 310: Tungsten & Memory Management**

*   Mục tiêu: Hiểu tối ưu hóa mức thấp của Spark.
    
*   Lý thuyết: Off-heap memory management, whole-stage code generation.
    
*   Thực hành: Đọc tài liệu Tungsten, tóm tắt bằng reading log cách nó giảm overhead JVM.
    

**Ngày 311: DAG & Job Scheduling**

*   Mục tiêu: Hiểu Spark chia job thành stage/task thế nào.
    
*   Lý thuyết: DAG scheduler, stage boundary (do shuffle), task.
    
*   Thực hành: Xem Spark UI của 1 job đã chạy, xác định số stage và lý do chia stage.
    

**Ngày 312: Caching & Persistence**

*   Mục tiêu: Tối ưu khi tái sử dụng DataFrame nhiều lần.
    
*   Lý thuyết: `.cache()` vs `.persist()`, storage level.
    
*   Thực hành: Đo tốc độ pipeline có và không có cache khi DataFrame được dùng lại 3 lần.
    

**Ngày 313: UDF & Performance Trade-off**

*   Mục tiêu: Hiểu khi nào cần UDF và cái giá phải trả.
    
*   Lý thuyết: Python UDF chậm hơn native function vì serialization qua JVM boundary; Pandas UDF (vectorized) nhanh hơn.
    
*   Thực hành: So sánh tốc độ 1 phép biến đổi bằng UDF thường vs Pandas UDF.
    

**Ngày 314: Đọc/Ghi với Table Format trong Spark**

*   Mục tiêu: Kết nối kiến thức tuần 9-10 với Spark thực tế.
    
*   Lý thuyết: Đọc/ghi Iceberg/Delta table bằng Spark, các option quan trọng.
    
*   Thực hành: Viết pipeline Spark đọc từ Bronze Iceberg table, transform, ghi ra Silver Iceberg table.
    

**Ngày 315: Spark Performance Tuning tổng hợp**

*   Mục tiêu: Áp dụng toàn bộ kỹ thuật tối ưu đã học.
    
*   Lý thuyết: Checklist tuning (partition size, broadcast threshold, caching, AQE - Adaptive Query Execution).
    
*   Thực hành: Tối ưu 1 pipeline chạy chậm (cố ý viết kém hiệu quả) áp dụng toàn bộ kỹ thuật đã học, đo cải thiện.
    

**Ngày 316: Adaptive Query Execution (AQE)**

*   Mục tiêu: Hiểu tính năng tự động tối ưu runtime của Spark hiện đại.
    
*   Lý thuyết: AQE tự điều chỉnh partition, join strategy dựa trên runtime statistics.
    
*   Thực hành: Bật/tắt AQE, so sánh execution plan và thời gian chạy trên cùng 1 job.
    

**Ngày 317: Spark trên Cluster thực tế**

*   Mục tiêu: Hiểu vận hành Spark ngoài môi trường local.
    
*   Lý thuyết: Cluster manager (YARN, Kubernetes, Standalone), managed Spark (Databricks, EMR, Dataproc).
    
*   Thực hành: Đọc tài liệu 1 managed Spark service, ghi chú cách submit job.
    

**Ngày 318: Reading Log #8 - Đọc source Spark Catalyst**

*   Mục tiêu: Đào sâu hiểu biết internals qua đọc mã nguồn/tài liệu chính thức.
    
*   Lý thuyết: Ghi lại vấn đề Catalyst giải quyết, cấu trúc module, 1-2 pattern thiết kế đáng chú ý.
    
*   Thực hành: Đọc phần tài liệu/blog kỹ thuật chính thức về Catalyst Optimizer, viết reading log.
    

**Ngày 319: Dự án Spark - Pipeline Batch hoàn chỉnh**

*   Mục tiêu: Tổng hợp toàn bộ tuần 11-13.
    
*   Lý thuyết: Không có lý thuyết mới.
    
*   Thực hành: Xây pipeline Spark batch hoàn chỉnh: đọc Bronze → transform → ghi Silver/Gold dạng Iceberg, có tối ưu partition/join/cache.
    

**Ngày 320: Ôn tập Spark tổng hợp**

*   Mục tiêu: Củng cố kiến thức trước khi sang Streaming.
    
*   Lý thuyết: Sơ đồ hóa lại toàn bộ Spark: kiến trúc → API → internals → tuning.
    
*   Thực hành: Làm bộ câu hỏi tự kiểm tra (10 câu) về Spark internals.
    

## Tuần 14-15 - Streaming: Apache Kafka (Ngày 321-334)

**Ngày 321: Kafka - Khái niệm cơ bản**

*   Mục tiêu: Hiểu vì sao cần message queue/streaming platform.
    
*   Lý thuyết: Producer, consumer, topic, message - Kafka giải quyết vấn đề gì so với batch.
    
*   Thực hành: Cài Kafka local (Docker), tạo 1 topic, gửi/nhận message bằng CLI.
    

**Ngày 322: Kafka - Partition**

*   Mục tiêu: Hiểu cách Kafka scale và đảm bảo thứ tự message.
    
*   Lý thuyết: Partition là gì, message key quyết định partition nào, thứ tự chỉ đảm bảo trong 1 partition.
    
*   Thực hành: Tạo topic với 3 partition, gửi message có key khác nhau, quan sát phân bố.
    

**Ngày 323: Kafka - Producer API**

*   Mục tiêu: Viết producer thực tế bằng Python.
    
*   Lý thuyết: `acks`, batching, retry trong producer config.
    
*   Thực hành: Viết producer Python (`kafka-python` hoặc `confluent-kafka`) gửi event giả lập (VD: page view event).
    

**Ngày 324: Kafka - Consumer API & Consumer Group**

*   Mục tiêu: Viết consumer và hiểu cơ chế scale đọc song song.
    
*   Lý thuyết: Consumer group, rebalancing, offset.
    
*   Thực hành: Viết consumer đọc event từ topic Ngày 323, chạy 2 consumer cùng group để thấy load balancing.
    

**Ngày 325: Kafka - Offset Management**

*   Mục tiêu: Kiểm soát việc đọc lại/bỏ qua dữ liệu.
    
*   Lý thuyết: Auto-commit vs manual commit, `earliest` vs `latest`.
    
*   Thực hành: Viết consumer với manual commit, thử reset offset về đầu để đọc lại toàn bộ dữ liệu.
    

**Ngày 326: Broker - Internals**

*   Mục tiêu: Hiểu cách Kafka lưu trữ dữ liệu bền vững.
    
*   Lý thuyết: Log segment, retention policy, cách broker ghi dữ liệu tuần tự lên đĩa.
    
*   Thực hành: Cấu hình retention policy (theo thời gian và dung lượng) cho 1 topic, quan sát file log segment trên đĩa (trong container).
    

**Ngày 327: ISR (In-Sync Replicas)**

*   Mục tiêu: Hiểu cơ chế đảm bảo độ tin cậy của Kafka.
    
*   Lý thuyết: Replication factor, leader/follower, ISR.
    
*   Thực hành: Đọc tài liệu ISR, mô phỏng kịch bản 1 broker chết và cách Kafka failover (qua tài liệu, vì cluster nhiều broker khó dựng local).
    

**Ngày 328: Controller & Raft (KRaft)**

*   Mục tiêu: Hiểu kiến trúc quản lý cluster hiện đại của Kafka.
    
*   Lý thuyết: Vai trò Controller, chuyển đổi từ ZooKeeper sang KRaft (Raft consensus).
    
*   Thực hành: Đọc tài liệu KRaft, tóm tắt lý do Kafka bỏ ZooKeeper.
    

**Ngày 329: Schema Registry**

*   Mục tiêu: Quản lý schema cho message một cách an toàn (liên hệ Data Contracts đã học ở Phase 2).
    
*   Lý thuyết: Avro/Protobuf schema, schema evolution compatibility (backward/forward).
    
*   Thực hành: Đăng ký 1 Avro schema cho topic, thử gửi message vi phạm schema để xem lỗi.
    

**Ngày 330: Kafka Connect**

*   Mục tiêu: Hiểu cách đưa dữ liệu vào/ra Kafka mà không cần code custom.
    
*   Lý thuyết: Source connector vs sink connector, ví dụ (Debezium CDC connector).
    
*   Thực hành: Đọc tài liệu Kafka Connect + Debezium, mô tả luồng CDC (Change Data Capture) từ Postgres vào Kafka.
    

**Ngày 331: Kafka Streams (khái niệm)**

*   Mục tiêu: Biết Kafka có thể xử lý stream ngay trong hệ sinh thái của nó.
    
*   Lý thuyết: Kafka Streams vs dùng Flink/Spark Streaming riêng - trade-off.
    
*   Thực hành: Đọc tài liệu Kafka Streams, so sánh use case với Flink (sẽ học tuần sau).
    

**Ngày 332: Kết nối Kafka với Spark Structured Streaming**

*   Mục tiêu: Kết nối 2 công nghệ đã học.
    
*   Lý thuyết: Spark Structured Streaming đọc từ Kafka, micro-batch model.
    
*   Thực hành: Viết pipeline Spark Structured Streaming đọc từ topic Kafka, tính aggregation theo cửa sổ thời gian (window), ghi ra console.
    

**Ngày 333: Reading Log #9 - Đọc source/tài liệu Kafka Internals**

*   Mục tiêu: Đào sâu hiểu biết qua tài liệu chính thức.
    
*   Lý thuyết: Ghi lại vấn đề Kafka giải quyết ở tầm hệ thống phân tán, kiến trúc log-based, pattern đáng nhớ.
    
*   Thực hành: Đọc phần "Kafka Design" trong tài liệu chính thức Apache Kafka, viết reading log.
    

**Ngày 334: Dự án Kafka tổng hợp**

*   Mục tiêu: Tổng hợp tuần 14-15.
    
*   Lý thuyết: Checklist thiết kế 1 hệ thống streaming ingestion.
    
*   Thực hành: Xây pipeline hoàn chỉnh: producer giả lập event → Kafka topic (có schema registry) → Spark Structured Streaming consume và ghi ra Bronze zone.
    

## Tuần 16-17 - Streaming: Apache Flink (Ngày 335-344)

**Ngày 335: Flink - Giới thiệu & So sánh với Spark Streaming**

*   Mục tiêu: Hiểu vì sao Flink được coi là "true streaming" so với micro-batch của Spark.
    
*   Lý thuyết: Streaming-first architecture, so sánh latency với Spark Structured Streaming.
    
*   Thực hành: Cài Flink local, chạy job "word count" streaming mẫu.
    

**Ngày 336: DataStream API**

*   Mục tiêu: Viết job Flink cơ bản.
    
*   Lý thuyết: Source, transformation, sink trong DataStream API.
    
*   Thực hành: Viết job Flink đọc từ Kafka topic (Ngày 323), thực hiện filter và map đơn giản.
    

**Ngày 337: Windowing trong Flink**

*   Mục tiêu: Xử lý dữ liệu theo cửa sổ thời gian.
    
*   Lý thuyết: Tumbling window, sliding window, session window.
    
*   Thực hành: Viết job tính số lượng event mỗi 1 phút bằng tumbling window.
    

**Ngày 338: Event Time vs Processing Time**

*   Mục tiêu: Hiểu khái niệm quan trọng nhất trong streaming xử lý dữ liệu trễ.
    
*   Lý thuyết: Event time (thời điểm sự kiện xảy ra) vs processing time (thời điểm hệ thống xử lý), watermark.
    
*   Thực hành: Cấu hình event time + watermark cho job Ngày 337, mô phỏng dữ liệu đến trễ và quan sát hành vi.
    

**Ngày 339: Watermark nâng cao**

*   Mục tiêu: Xử lý dữ liệu trễ (late data) hợp lý.
    
*   Lý thuyết: Watermark strategy, allowed lateness, side output cho late data.
    
*   Thực hành: Cấu hình allowed lateness, route late data ra side output riêng để xử lý sau.
    

**Ngày 340: State trong Flink**

*   Mục tiêu: Hiểu cách Flink lưu trạng thái giữa các event.
    
*   Lý thuyết: Keyed state, operator state, use case (đếm running total theo user).
    
*   Thực hành: Viết job dùng keyed state tính running total giao dịch theo từng user.
    

**Ngày 341: State Backend & Checkpoint**

*   Mục tiêu: Hiểu cách Flink đảm bảo fault-tolerance.
    
*   Lý thuyết: State backend (memory, RocksDB), checkpoint mechanism (Chandy-Lamport algorithm ở mức khái niệm).
    
*   Thực hành: Cấu hình checkpoint cho job đã viết, mô phỏng restart job và kiểm tra state được khôi phục.
    

**Ngày 342: Exactly-once Semantics**

*   Mục tiêu: Hiểu đảm bảo quan trọng nhất của hệ thống streaming production.
    
*   Lý thuyết: At-most-once, at-least-once, exactly-once - cách Flink đạt được qua checkpoint + 2PC với sink.
    
*   Thực hành: Đọc tài liệu, giải thích bằng sơ đồ cách Flink đảm bảo exactly-once khi ghi ra Kafka sink.
    

**Ngày 343: So sánh Kafka Streams vs Flink vs Spark Structured Streaming**

*   Mục tiêu: Có tiêu chí chọn công cụ streaming phù hợp.
    
*   Lý thuyết: So sánh latency, độ phức tạp vận hành, hệ sinh thái.
    
*   Thực hành: Viết bảng so sánh 3 công cụ, đề xuất lựa chọn cho 2 kịch bản (fraud detection real-time vs dashboard cập nhật mỗi 5 phút).
    

**Ngày 344: Dự án Flink tổng hợp**

*   Mục tiêu: Tổng hợp tuần 16-17.
    
*   Lý thuyết: Checklist thiết kế job streaming production-ready.
    
*   Thực hành: Xây job Flink hoàn chỉnh: đọc Kafka → windowing + watermark → keyed state aggregation → ghi ra sink (Kafka topic khác hoặc file).
    

## Tuần 18 - Query Engine: Trino (Ngày 345-349)

**Ngày 345: Trino - Giới thiệu**

*   Mục tiêu: Hiểu vai trò query engine phân tán truy vấn qua nhiều nguồn dữ liệu.
    
*   Lý thuyết: Trino (trước là PrestoSQL) - federated query engine, tách biệt compute khỏi storage.
    
*   Thực hành: Cài Trino local (Docker), kết nối tới catalog Iceberg đã xây ở tuần 9-10.
    

**Ngày 346: Trino - Kiến trúc**

*   Mục tiêu: Hiểu cách Trino thực thi truy vấn phân tán.
    
*   Lý thuyết: Coordinator, worker, connector architecture.
    
*   Thực hành: Chạy `EXPLAIN` cho 1 truy vấn Trino, phân tích query plan.
    

**Ngày 347: Federated Query - Truy vấn nhiều nguồn cùng lúc**

*   Mục tiêu: Tận dụng khả năng đặc trưng nhất của Trino.
    
*   Lý thuyết: Join dữ liệu giữa Iceberg table và 1 nguồn khác (VD: Postgres) trong cùng 1 truy vấn.
    
*   Thực hành: Cấu hình 2 catalog (Iceberg + Postgres) trong Trino, viết truy vấn JOIN giữa 2 nguồn.
    

**Ngày 348: Trino Performance Tuning cơ bản**

*   Mục tiêu: Viết truy vấn Trino hiệu quả.
    
*   Lý thuyết: Predicate pushdown qua connector, phân bổ resource cho worker.
    
*   Thực hành: Tối ưu 1 truy vấn Trino chạy chậm bằng cách tận dụng partition pruning trên Iceberg table.
    

**Ngày 349: Dự án Trino tổng hợp**

*   Mục tiêu: Tổng hợp tuần 18.
    
*   Lý thuyết: Vai trò Trino trong kiến trúc lakehouse tổng thể (kết nối dbt, BI tool tới lake).
    
*   Thực hành: Kết nối Power BI/Tableau (đã học Phase 1) tới Trino, thử query trực tiếp Iceberg table qua BI tool.
    

## Tuần 19-20 - Orchestration (Ngày 350-359)

**Ngày 350: Vì sao cần Orchestration**

*   Mục tiêu: Hiểu vấn đề (dependency, scheduling, retry) mà orchestrator giải quyết.
    
*   Lý thuyết: Vấn đề khi dùng cron thuần cho pipeline nhiều bước phụ thuộc nhau.
    
*   Thực hành: Vẽ sơ đồ dependency của toàn bộ pipeline đã xây từ Phase 2-3 (Kafka → Spark → Iceberg → dbt), xác định thứ tự chạy.
    

**Ngày 351: Airflow - Kiến trúc & DAG cơ bản**

*   Mục tiêu: Làm quen orchestrator phổ biến nhất.
    
*   Lý thuyết: Scheduler, webserver, executor, DAG là gì.
    
*   Thực hành: Cài Airflow (Docker), viết DAG đầu tiên với 3 task nối tiếp nhau.
    

**Ngày 352: Airflow - Operators**

*   Mục tiêu: Sử dụng các loại task khác nhau.
    
*   Lý thuyết: PythonOperator, BashOperator, các operator tích hợp sẵn (S3, Spark, dbt).
    
*   Thực hành: Viết DAG chạy script Python và 1 lệnh bash trong cùng pipeline.
    

**Ngày 353: Airflow - Scheduling & Backfill**

*   Mục tiêu: Hiểu cơ chế lập lịch của Airflow.
    
*   Lý thuyết: `schedule_interval`, `execution_date`, backfill là gì.
    
*   Thực hành: Cấu hình DAG chạy hàng ngày, thử backfill cho 5 ngày trong quá khứ.
    

**Ngày 354: Airflow - Task Dependencies phức tạp**

*   Mục tiêu: Xây pipeline nhiều nhánh.
    
*   Lý thuyết: Branching (`BranchPythonOperator`), trigger rules, dynamic task mapping.
    
*   Thực hành: Viết DAG có branching logic (VD: chỉ chạy nhánh B nếu check dữ liệu ở nhánh A pass).
    

**Ngày 355: Airflow - Sensors & Retry**

*   Mục tiêu: Xử lý pipeline phụ thuộc vào sự kiện bên ngoài.
    
*   Lý thuyết: Sensor chờ file/điều kiện, retry policy, alerting khi fail.
    
*   Thực hành: Viết DAG dùng sensor chờ file xuất hiện trên S3 trước khi chạy transform.
    

**Ngày 356: Airflow - Tích hợp toàn bộ Pipeline**

*   Mục tiêu: Orchestrate toàn bộ hệ thống đã xây từ đầu Phase 3.
    
*   Lý thuyết: Không có lý thuyết mới.
    
*   Thực hành: Viết 1 DAG lớn: trigger Spark batch job → chạy dbt → chạy data quality check → gửi thông báo hoàn tất.
    

**Ngày 357: Dagster - Giới thiệu & So sánh với Airflow**

*   Mục tiêu: Làm quen orchestrator hiện đại theo hướng "asset-based".
    
*   Lý thuyết: Software-defined assets, khác biệt tư duy task-based (Airflow) vs asset-based (Dagster).
    
*   Thực hành: Cài Dagster, viết lại 1 phần pipeline Ngày 356 theo asset-based model, so sánh trải nghiệm.
    

**Ngày 358: Prefect - Giới thiệu & So sánh**

*   Mục tiêu: Biết thêm lựa chọn thứ 3, nhẹ và Pythonic hơn.
    
*   Lý thuyết: Prefect flow/task, dynamic workflow, điểm mạnh cho team nhỏ.
    
*   Thực hành: Viết 1 flow Prefect đơn giản, so sánh độ phức tạp setup với Airflow.
    

**Ngày 359: Dự án Orchestration tổng hợp**

*   Mục tiêu: Tổng hợp tuần 19-20.
    
*   Lý thuyết: Bảng so sánh Airflow vs Dagster vs Prefect - tiêu chí chọn theo quy mô team.
    
*   Thực hành: Hoàn thiện DAG/flow orchestrate toàn bộ pipeline end-to-end bằng công cụ đã chọn (khuyến nghị Airflow vì phổ biến nhất trong tuyển dụng).
    

## Tuần 21 - Metadata Management (Ngày 360-362)

**Ngày 360: DataHub - Giới thiệu**

*   Mục tiêu: Hiểu vai trò data catalog trong hệ sinh thái lớn.
    
*   Lý thuyết: Metadata graph, lineage tracking tự động, search & discovery.
    
*   Thực hành: Cài DataHub (Docker), ingest metadata từ dbt project đã có ở Phase 2.
    

**Ngày 361: OpenMetadata & So sánh**

*   Mục tiêu: Biết thêm lựa chọn thay thế mã nguồn mở.
    
*   Lý thuyết: So sánh DataHub vs OpenMetadata về kiến trúc, độ dễ triển khai.
    
*   Thực hành: Đọc tài liệu OpenMetadata, ghi chú khác biệt chính so với DataHub.
    

**Ngày 362: Column-level Lineage End-to-End**

*   Mục tiêu: Thấy toàn cảnh lineage từ Kafka đến dashboard.
    
*   Lý thuyết: Cách ghép lineage từ nhiều hệ thống (Kafka → Spark → Iceberg → dbt → BI) thành 1 bức tranh thống nhất trong catalog.
    
*   Thực hành: Cấu hình DataHub ingest thêm từ Airflow và Iceberg, xem lineage graph tổng thể của toàn bộ pipeline đã xây.
    

## Tuần 21-22 - Capstone Phase 3 (Ngày 363-364)

**Ngày 363: Capstone - Hoàn thiện Pipeline End-to-End**

*   Mục tiêu: Ghép toàn bộ Phase 3 thành 1 hệ thống thống nhất.
    
*   Lý thuyết: Kiến trúc mục tiêu: `Kafka → Spark → Iceberg → Trino → dbt → Power BI`, orchestrate bởi Airflow.
    
*   Thực hành: Đảm bảo toàn bộ pipeline chạy end-to-end tự động qua Airflow DAG, dữ liệu chảy đúng từ ingestion đến dashboard.
    

**Ngày 364: Capstone - Kiểm thử, Tài liệu hóa & Tổng kết Phase 3**

*   Mục tiêu: Đưa hệ thống đạt chuẩn production và kết thúc Phase 3.
    
*   Lý thuyết: Checklist hệ thống data platform hoàn chỉnh (observability, data quality, lineage, documentation).
    
*   Thực hành: Viết tài liệu kiến trúc tổng thể (kèm sơ đồ) cho toàn bộ hệ thống đã xây, cập nhật portfolio GitHub, tổng kết Phase 3 và lên kế hoạch Phase 4 (Machine Learning for Decision Making).
