dbt là gì: biến đổi dữ liệu bằng SQL như một dự án phần mềm
Xem thửNhóm analytics của GDev Mart có 80 tệp SQL nằm rải rác: một số trong thư mục chia sẻ, một số dán thẳng vào công cụ BI, một số chỉ có trong máy một người đã nghỉ việc. Mỗi tệp tạo một bảng từ bảng khác, nhưng không ai biết thứ tự chạy, không ai biết bảng nào phụ thuộc bảng nào, và khi đổi tên một cột, ba báo cáo hỏng mà không ai hay cho tới khi giám đốc phàn nàn. Không có bài kiểm thử, không có tài liệu, không có lịch sử thay đổi.
Hãy dự đoán trước khi đọc tiếp: nếu bạn muốn coi các tệp SQL này như mã nguồn của một phần mềm, bạn cần bổ sung những thực hành nào (nghĩ tới Git, kiểm thử, tài liệu, thứ tự chạy)? Hãy liệt kê ít nhất bốn thứ.
Sau bài này, bạn có thể
- Giải thích dbt làm gì và không làm gì trong pipeline ELT.
- Viết lời gọi
refvà dự đoán thứ tự chạy cùng tên bảng sau khi biên dịch. - Chia dự án thành ba lớp staging, intermediate, mart và chọn đúng giữa
dbt run,dbt testvàdbt build.
Cần biết trước: bài "ETL và ELT: biến đổi ở đâu và vì sao điều đó quan trọng", bài "Mô hình dimensional: fact, dimension và grain" và SQL SELECT, JOIN. Bạn cài dbt-postgres ở lab cuối chương.
Mô hình tư duy 1: dbt là lớp "T" của ELT, viết bằng SQL và quản lý như mã nguồn
dbt (data build tool) làm đúng một việc: biến đổi dữ liệu đã nằm trong kho (chữ T của ELT) bằng các câu lệnh SELECT. Bạn viết mỗi biến đổi thành một model (một tệp .sql chứa một SELECT), dbt lo phần còn lại: dựng thành bảng hoặc view, xác định thứ tự chạy, chạy kiểm thử, sinh tài liệu. Bạn không viết CREATE TABLE hay INSERT; bạn chỉ viết "bảng này là kết quả của truy vấn này".
Câu trả lời cho dự đoán đầu bài: dbt mang vào SQL các thực hành của phần mềm: Git (mọi model là tệp trong repo), kiểm thử (khai báo unique, not_null...), tài liệu (tự sinh từ khai báo), thứ tự chạy tự động (suy ra từ ref), và môi trường tách biệt (dev, prod).
Đang tải sơ đồ…
Cách đọc hình: dữ liệu đi từ nguồn thô qua ba lớp model. Staging dọn dẹp từng bảng nguồn (đổi tên, ép kiểu, chuẩn hóa), mỗi bảng nguồn một model. Intermediate gom nối và áp dụng quy tắc nghiệp vụ. Mart là mô hình dimensional cuối cùng cho người dùng (các bảng fact và dimension bạn học ở tuần 4). Mũi tên đứt biểu thị kiểm thử và tài liệu bám vào các model.
Mô hình tư duy 2: ref biến các tệp rời thành một đồ thị
Điểm cốt lõi của dbt là hàm ref. Khi model fct_orders cần dữ liệu từ stg_orders, bạn không viết tên bảng thật mà viết {{ ref('stg_orders') }}. dbt đọc mọi lời gọi ref để dựng một đồ thị phụ thuộc (DAG), rồi chạy các model theo đúng thứ tự, và thay ref bằng tên bảng thật theo môi trường (dbt_dev.stg_orders ở dev, analytics.stg_orders ở prod).
select
o.order_id,
o.created_at::date as order_date,
o.amount,
c.city
from {{ ref('stg_orders') }} as o
join {{ ref('stg_customers') }} as c on c.customer_id = o.customer_id
Phần {{ ... }} là Jinja, ngôn ngữ mẫu mà dbt chạy trước khi gửi SQL tới kho. Kết quả (gọi là SQL đã biên dịch) là SQL thuần:
select o.order_id, o.created_at::date as order_date, o.amount, c.city
from "gdevmart"."dbt_dev"."stg_orders" as o
join "gdevmart"."dbt_dev"."stg_customers" as c on c.customer_id = o.customer_id
Đang tải sơ đồ…
Cách đọc hình: bốn bước nối tiếp: phân tích, biên dịch, chạy, lưu. Điều quan trọng cần hiểu là dbt không tự xử lý dữ liệu: nó chỉ biên dịch SQL rồi gửi cho kho dữ liệu thực thi. Sức mạnh tính toán vẫn là của kho (PostgreSQL, ClickHouse, BigQuery, Snowflake).
Đang tải Animation…
Một dự án dbt trông như thế nào
gdevmart/
├── dbt_project.yml
├── models/
│ ├── staging/
│ │ ├── sources.yml
│ │ ├── stg_orders.sql
│ │ └── stg_customers.sql
│ └── marts/
│ ├── schema.yml
│ └── fct_orders.sql
├── macros/
├── snapshots/
└── tests/
Tệp dbt_project.yml đặt tên dự án và cấu hình chung (ví dụ lớp staging là view, lớp marts là table). Thông tin kết nối tới kho nằm riêng trong profiles.yml (không commit vào Git vì chứa mật khẩu).
Các lệnh bạn dùng hằng ngày:
| Lệnh | Việc làm |
|---|---|
dbt debug | Kiểm tra kết nối và cấu hình |
dbt run | Chạy các model |
dbt test | Chạy các kiểm thử |
dbt build | Chạy model, test, snapshot theo thứ tự phụ thuộc |
dbt docs generate | Sinh tài liệu và lineage |
dbt run --select stg_orders+ | Chạy stg_orders và mọi model phụ thuộc vào nó |
Giải đáp thêm: vì sao quy tắc đặt tên và ba lớp quan trọng
Mỗi lớp có quy tắc rõ ràng để dự án 500 model vẫn dễ đọc: staging chỉ làm sạch một bảng nguồn và không nối bảng; mart đặt tên có tiền tố fct_ (fact), dim_ (dimension). Nhờ vậy, khi quy tắc doanh thu sai, bạn biết ngay mình sửa ở một model intermediate hoặc mart thay vì lùng qua 80 tệp rời.
Phiên bản dbt dùng trong khóa học
Khóa học dùng dbt Core 1.x (cú pháp kiểm tra với 1.9 đến 1.11) cùng adapter dbt-postgres. Cùng thời gian, dbt Labs phát hành dòng v2 dựa trên dbt Fusion engine viết bằng Rust, đọc cùng dự án, cùng Jinja và YAML, nhưng kiểm tra cấu hình chặt hơn. Vì vậy các tệp YAML trong khóa đặt cấu hình theo cách mới (config: cho freshness, arguments: cho đối số của test, snapshot bằng YAML): chúng chạy trên dbt Core 1.9 trở lên và ít bị cảnh báo khi bạn nâng cấp. Khi đọc ví dụ cũ trên mạng, hãy kiểm tra khóa nào thuộc phiên bản nào trước khi sao chép.
Những hiểu lầm thường gặp
- "dbt là công cụ nạp dữ liệu." dbt không trích xuất hay nạp dữ liệu; nó biến đổi dữ liệu đã có trong kho.
- "dbt chạy SQL trên máy tôi." dbt chạy trên máy bạn chỉ để biên dịch và gửi lệnh; mọi xử lý nằm ở kho dữ liệu.
- "
refchỉ là tên bảng."refcòn tạo phụ thuộc để dbt xác định thứ tự và vẽ lineage. - "Một model khổng lồ cho tiện." Model lớn khó đọc và khó kiểm thử; chia nhỏ theo lớp giúp sửa và tái sử dụng.
Tự kiểm tra (có đáp án)
Câu 1. Vì sao fct_orders dùng {{ ref('stg_orders') }} thay vì ghi tên bảng dbt_dev.stg_orders?
Đáp án: để dbt biết phụ thuộc (chạy stg_orders trước) và tự đổi tên bảng theo môi trường (dev, prod) mà không sửa mã.
Câu 2. dbt có xử lý trực tiếp dữ liệu 100 GB trong máy của bạn không? Đáp án: không; dbt chỉ biên dịch SQL và gửi cho kho dữ liệu thực thi, nên tốc độ phụ thuộc vào kho.
Câu 3. Lớp staging nên làm gì và không nên làm gì? Đáp án: nên đổi tên cột, ép kiểu, chuẩn hóa giá trị của đúng một bảng nguồn; không nên nối nhiều bảng hay áp dụng quy tắc nghiệp vụ phức tạp, vì đó là việc của intermediate và mart.
Nếu chỉ nhớ 3 điều
- dbt biến đổi dữ liệu trong kho bằng
SELECT, mang Git, kiểm thử và tài liệu vào SQL. reftạo đồ thị phụ thuộc: dbt tự sắp thứ tự chạy và đổi tên bảng theo môi trường.- Ba lớp staging, intermediate, mart giữ dự án lớn vẫn dễ đọc; dbt chỉ biên dịch và gửi SQL, kho mới là nơi tính toán.
Nguồn tham khảo
- What is dbt?, kiểm tra ngày 2026-10-28
- About ref function, kiểm tra ngày 2026-10-28
- About dbt build command, kiểm tra ngày 2026-10-28