← Kỹ sư dữ liệu← Data Engineer
Kỹ sư dữ liệuData Engineer19 Th7, 2026Jul 19, 202622 phút đọc17 min read

Analytics, BI & Data ServingAnalytics, BI & Data Serving

Thuộc bộ kiến thức Data Engineer Roadmap.

Tổng quan

Từ đầu đến giờ, các bài trong bộ kiến thức này đều xoay quanh việc đưa dữ liệu vào một nơi được tổ chức tốt: ingest dữ liệu (./03-data-sources-and-ingestion.md), modeling vào warehouse (./06-data-modeling-and-warehousing.md), và di chuyển qua các pipeline (./08-etl-elt-and-data-pipelines.md). Tất cả công sức đó chỉ thực sự có giá trị khi có ai đó — hoặc hệ thống nào đó — thật sự tiêu thụ (consume) kết quả. Serving layer (tầng phục vụ dữ liệu) là giai đoạn cuối cùng của data engineering lifecycle: nơi dữ liệu đã được modeling, đáng tin cậy, được expose ra cho con người thông qua dashboard và các công cụ self-service BI, cho hệ thống khác thông qua API và reverse ETL, và cho các mô hình machine learning thông qua feature store. Công việc của một data engineer chưa hoàn thành khi một dbt run chạy thành công; nó chỉ hoàn thành khi một nhân viên sales nhìn thấy đúng con số trong Salesforce, một lãnh đạo tin tưởng biểu đồ revenue trên dashboard, hay một model fraud detection chấm điểm một giao dịch theo thời gian thực bằng các feature được tính đúng.

Bài này cố tình tập trung vào “chặng cuối cùng” (last mile). Nó không giải thích lại cách modeling warehouse hay xây pipeline — nó giải thích điều xảy ra sau khi công việc đó hoàn tất: các công cụ BI như Tableau, Looker, Power BI biến một warehouse được modeling tốt thành dashboard nhanh và đáng tin cậy như thế nào; tại sao cần một semantic layer để ngăn năm dashboard hiển thị năm con số khác nhau cho “revenue”; các công cụ nhẹ như Streamlit nằm ở đâu so với các nền tảng BI đầy đủ; data engineer giúp analyst phân tích sâu hơn mà không tự làm phân tích đó như thế nào; kỷ luật kỹ thuật đứng sau việc A/B testing đáng tin cậy; và vấn đề đặc thù của serving layer — training-serving skew — mà feature store được sinh ra để giải quyết.

Kiến thức nền tảng

Serving layer — giai đoạn cuối của lifecycle

Có thể hình dung data engineering lifecycle kết thúc bằng một điểm phân nhánh (fan-out) chứ không phải một đích đến duy nhất. Sau khi dữ liệu được extract, lưu trữ, và transform thành các bảng modeling sạch, nó tỏa ra bất cứ nơi nào tạo ra giá trị:

Phục vụ dữ liệu từ warehouse đã modeling
Warehouse đã modelingmarts
  • con người khám phá trực quan
    BI toolTableau, Looker, Power BI
  • các công cụ SaaS vận hành
    Reverse ETL
  • ML training & inference
    Feature store
  • analyst, data scientist
    Ad-hoc SQL / notebook

Mỗi consumption pattern này có yêu cầu khác nhau về độ tươi (freshness), độ trễ (latency), và hình dạng truy vấn (query shape), và mỗi cái sẽ hỏng theo một cách riêng nếu data engineer coi “model đã build xong” là vạch đích. Một mart hoàn hảo cho việc refresh BI hằng đêm có thể quá chậm, hoặc quá cũ, để phục vụ một feature store cho inference thời gian thực. Thiết kế serving layer tốt nghĩa là hiểu, với từng consumer, không chỉ dữ liệu gì họ cần mà còn nhanh đến đâu, tần suất ra sao, và hình dạng nào — và sự hiểu biết đó phải có trước khi pipeline được xây, chứ không phải sau khi phát hiện dashboard chậm đến mức không dùng được.

Business Intelligence (BI) tools

Các công cụ BI tồn tại để cho phép những người không viết SQL — hoặc không muốn viết SQL mỗi lần — khám phá dữ liệu trực quan và xây dashboard mà không cần đội engineering hỗ trợ. Ba cái tên thống trị đều đi từ cùng một ý tưởng nền tảng (kết nối tới warehouse, modeling hoặc map các bảng của nó, cho người dùng kéo-thả field lên canvas để tạo chart) nhưng khác nhau về triết lý:

Công cụMô hình hoạt độngĐiểm mạnh nổi bật
TableauKết nối tới warehouse hoặc extract dữ liệu vào engine in-memory riêng (Hyper)Khám phá trực quan và phân tích ad-hoc “kéo-thả” hàng đầu; phù hợp cho analyst muốn tự do đào sâu dữ liệu
LookerQuery-pushdown — luôn query trực tiếp warehouse, không bao giờ extract dữ liệu ra riêngLookML, một semantic modeling layer được version-control (xem bên dưới) tập trung hóa định nghĩa metric và dimension
Power BIKết nối tới warehouse hoặc import dữ liệu vào engine columnar riêng (VertiPaq)Tích hợp sâu với hệ sinh thái Microsoft (Excel, Azure, Teams); DAX cho các measure tính toán

Điểm chung của cả ba là chúng chỉ tốt bằng chất lượng dữ liệu bên dưới. Một BI tool là một thấu kính, không phải một cách sửa lỗi — nó hiển thị bất cứ thứ gì warehouse cung cấp, với tốc độ mà warehouse có thể trả lời một query. Đây là lý do bài về data modeling trước đó liên quan trực tiếp đến đây: một warehouse được modeling tốt — cụ thể là star schema (./06-data-modeling-and-warehousing.md) với các bảng fact và dimension sạch sẽ — chính là thứ khiến BI tool cảm giác nhanh và đáng tin cậy, còn một warehouse đầy các bảng raw không được quản trị và join tùy tiện là thứ khiến chúng cảm giác chậm và rối rắm.

Hai cơ chế cụ thể giải thích tại sao model lại quan trọng đến vậy:

Khám phá self-service và giới hạn của nó

Lời hứa của BI tool là self-service: một trưởng nhóm marketing tự xây biểu đồ hiệu suất chiến dịch của mình mà không cần mở ticket cho đội dữ liệu. Điều này thực sự hiệu quả khi warehouse được modeling tốt, bởi self-service exploration thực chất là “để người không phải kỹ sư tự kết hợp các khối xây dựng (fact, dimension, metric) đã được định nghĩa sẵn và đáng tin cậy”, chứ không phải “để bất kỳ ai viết SQL tùy ý trên dữ liệu raw”. Công việc của data engineer là xây và duy trì những khối xây dựng đó; BI tool và semantic layer là thứ khiến việc kết hợp chúng an toàn cho những người không có nền tảng data engineering.

Khái niệm chính

Semantic layer: một metric, định nghĩa một lần duy nhất

Ý tưởng quan trọng nhất trong bài này là semantic layer: một tầng được quản trị (governed), nằm giữa warehouse và mọi BI tool hay dashboard, nơi các metric và dimension nghiệp vụ được định nghĩa đúng một lần — “active user”, “revenue”, “churned customer” — và mọi consumer phía sau tham chiếu tới định nghĩa duy nhất đó thay vì tự tính lại.

Vấn đề mà semantic layer giải quyết rất quen thuộc với bất kỳ ai từng làm ở công ty có nhiều hơn một dashboard: năm dashboard khác nhau hiển thị năm con số khác nhau cho “revenue”, vì năm người khác nhau viết năm câu SQL khác nhau, mỗi câu mang một giả định hơi khác. “Revenue” của analyst này bao gồm thuế; của người khác thì loại trừ refund; người thứ ba join theo order_date trong khi người thứ tư join theo shipped_date. Không ai trong số họ nói dối — mỗi người chỉ đưa ra một lựa chọn nghe có vẻ hợp lý một cách độc lập, và không có một nơi duy nhất để tra cứu định nghĩa “chính thức”. Kết quả là một cuộc khủng hoảng niềm tin: ban lãnh đạo ngừng tin dashboard, và mỗi con số lại bị tranh cãi lại trong các cuộc họp thay vì thúc đẩy quyết định.

Semantic layer sửa vấn đề này về mặt cấu trúc chứ không dựa vào kỷ luật hay email nhắc nhở. Metric được định nghĩa một lần, thường ở dạng code:

# Ví dụ: một metric định nghĩa một lần trong semantic layer (kiểu dbt Semantic Layer / MetricFlow)
metrics:
  - name: revenue
    label: "Revenue"
    description: "Doanh thu thuần ghi nhận: tổng giá trị đơn hàng trừ refund, không tính thuế."
    type: simple
    type_params:
      measure: net_order_amount
    filter: |
      {{ Dimension('order__status') }} = 'completed'
# Ví dụ: cùng ý tưởng được thể hiện bằng LookML, semantic modeling layer của Looker
measure: revenue {
  type: sum
  sql: ${TABLE}.net_order_amount ;;
  filters: [order.status: "completed"]
  description: "Doanh thu thuần ghi nhận: tổng giá trị đơn hàng trừ refund, không tính thuế."
}

Mọi dashboard, mọi ad-hoc query đi qua semantic layer, và mọi BI tool kết nối tới nó giờ đây kế thừa cùng một revenue — thay đổi định nghĩa một lần (chẳng hạn bộ phận tài chính quyết định revenue nên được ghi nhận theo shipped_date thay vì order_date) và mọi consumer cập nhật đồng bộ, thay vì phải lùng sục và sửa mười hai câu SQL riêng lẻ nằm rải rác trong các dashboard mà không ai còn nhớ ai đã xây.

LookML đáng được nhắc riêng ở đây vì đây là một trong những triển khai được áp dụng rộng rãi sớm nhất của ý tưởng này: thay vì mỗi dashboard Looker chứa SQL riêng, LookML định nghĩa dimension và measure một lần, trong các file .lkml được version-control, và mọi “Explore” cũng như dashboard trong Looker được sinh ra từ model chung đó. dbt Semantic Layer gần đây hơn (xây trên nền MetricFlow) tổng quát hóa cùng ý tưởng đó ra ngoài phạm vi của bất kỳ một BI tool cụ thể nào — các metric được định nghĩa một lần trong dbt project cùng với các model mà chúng được xây dựng từ đó, và bất kỳ BI tool nào có tích hợp semantic layer (không riêng của một vendor) đều có thể query chúng một cách nhất quán. Công cụ cụ thể không quan trọng bằng nguyên tắc: định nghĩa metric thuộc về một tầng được quản trị, version-control, chứ không phải rải rác trong SQL riêng của từng dashboard.

Streamlit và các internal app nhẹ

Không phải nhu cầu dữ liệu nội bộ nào cũng đáng để chịu chi phí — về license, setup, và overhead quản trị — của một nền tảng BI đầy đủ. Streamlit (và các framework tương tự như Gradio hay Dash) cho phép data engineer hoặc analyst biến một script Python thành một web app tương tác chỉ trong vài chục dòng code, mà không cần đụng tới HTML, CSS, hay JavaScript:

import streamlit as st
import pandas as pd

df = pd.read_sql("select * from fct_orders", con=warehouse_connection)

st.title("Orders Dashboard")
region = st.selectbox("Region", df["region"].unique())
filtered = df[df["region"] == region]

st.metric("Total Revenue", f"${filtered['amount_usd'].sum():,.2f}")
st.bar_chart(filtered.groupby("order_month")["amount_usd"].sum())

Vị trí ngách của nó so với Tableau, Looker, hay Power BI hẹp nhưng có thật: các công cụ nội bộ nhanh gọn cho một nhóm người dùng nhỏ — một app khám phá dùng một lần cho đội data science, một công cụ QA nội bộ để review kết quả pipeline, một dashboard prototype trước khi quyết định một metric có xứng đáng có một “ngôi nhà” lâu dài trong stack BI thật sự hay không. Điều nó cố tình không cung cấp là chính điều mà một nền tảng BI đầy đủ được xây dựng để làm: governance cấp doanh nghiệp, row-level security, semantic layer dùng chung, phân phối theo lịch cho hàng trăm người dùng nghiệp vụ, hay trải nghiệm self-service bóng bẩy cho nhân viên không rành kỹ thuật. Quy tắc chung: dùng Streamlit khi đối tượng nhỏ, kỹ thuật, và nội bộ; dùng nền tảng BI khi đối tượng rộng, không rành kỹ thuật, và cần các metric khớp với mọi dashboard khác trong công ty.

Thực hành data analytics: analyst làm gì với những gì engineer xây

Đáng để làm rõ sự phân công lao động ngụ ý trong tất cả những gì ở trên. Descriptive analytics (mô tả — chuyện gì đã xảy ra) phần lớn là công việc của BI tool: nó trả lời các câu hỏi như “revenue quý trước là bao nhiêu” hay “khu vực nào tăng trưởng nhanh nhất”, và đây chính xác là loại câu hỏi mà một warehouse được modeling tốt cùng semantic layer được xây dựng để trả lời nhanh và nhất quán. Xa hơn nữa là phân tích sâu hơn: diagnostic analytics (tại sao chuyện đó xảy ra), và những công việc pha trộn vào data science — phân tích cohort, kiểm định thống kê, suy luận nhân quả (causal inference), dự báo (forecasting).

Vai trò của data engineer trong công việc sâu hơn này là hỗ trợ (enabling), không phải thực hiện. Data engineer thường không chạy hồi quy hay thiết kế phân tích cohort; data engineer đảm bảo pipeline nuôi phân tích đó tạo ra các data model sạch, tài liệu hóa đầy đủ, hiệu năng tốt, để analyst hoặc data scientist có thể dành thời gian cho câu hỏi phân tích thực sự thay vì cho việc “khảo cổ dữ liệu” — truy tìm tại sao một join tạo ra hàng trùng lặp, hay tại sao ý nghĩa của một cột thay đổi âm thầm ba tháng trước. Dấu hiệu rõ ràng nhất của một bàn giao lành mạnh là analyst dành phần lớn thời gian đặt và trả lời câu hỏi nghiệp vụ, và chỉ hiếm khi phải đào sâu vào bảng nguồn raw vì có gì đó trong tầng modeling không khớp.

Hạ tầng A/B testing

Thử nghiệm (experimentation) là một trong những ví dụ sắc nét nhất về việc “data engineering vẫn quan trọng dù câu hỏi thú vị là một câu hỏi thống kê”. Một A/B test chỉ đáng tin cậy bằng chính các event nuôi nó, và có một số điểm hỏng đặc thù kỹ thuật có thể âm thầm vô hiệu hóa một thí nghiệm được thiết kế tốt về mặt thống kê:

Yêu cầu kỹ thuật ở đây hẹp nhưng không thể thương lượng: một event pipeline (./08-etl-elt-and-data-pipelines.md, ./11-streaming-and-realtime-data.md) ghi nhận event assignment và outcome với đảm bảo delivery mạnh, định danh ổn định tồn tại suốt thời gian thí nghiệm, và giám sát tự động phát hiện SRM cùng các bất thường pipeline khác — bởi một nhà thống kê ở cuối chuỗi không thể sửa được dữ liệu thiếu hoặc join sai, dù bài kiểm định ý nghĩa có tinh vi đến đâu.

Feature store và training-serving skew

Việc tiêu thụ serving layer cho machine learning có một vấn đề mà BI dashboard không có: cùng một feature — chẳng hạn “số lần mua hàng của khách này trong 30 ngày qua” — phải được tính giống hệt nhau trong hai bối cảnh rất khác nhau. Trong quá trình training, nó được tính hàng loạt trên dữ liệu lịch sử, thường bằng một job SQL hoặc Spark batch. Trong quá trình inference (phục vụ dự đoán thời gian thực), nó phải được tính cho một entity duy nhất, ngay lúc này, thường với ngân sách độ trễ tính bằng mili giây, đôi khi từ một code path hoàn toàn khác hoặc thậm chí một service của một đội khác. Nếu hai phép tính này lệch nhau dù chỉ một chút — xử lý múi giờ khác nhau, lệch một đơn vị trong cửa sổ lookback, định nghĩa “giao dịch mua” hơi khác — model sẽ thấy giá trị feature khác trong production so với lúc nó được huấn luyện, và độ chính xác của nó âm thầm giảm sút. Đây là training-serving skew, và đây là một trong những nguyên nhân phổ biến nhất khiến một model chấm điểm tốt offline nhưng lại kém trong production.

Một feature store (Feast, Tecton, hoặc dịch vụ native trên cloud như SageMaker Feature Store) là serving layer chuyên biệt được xây để đóng khoảng cách này. Nó tính một feature một lần, từ một định nghĩa transformation duy nhất, và lưu trữ dưới hai dạng được giữ nhất quán với nhau: một offline store (thường là warehouse hoặc lake, chứa giá trị feature lịch sử để training) và một online store (một key-value store độ trễ thấp, thường dựa trên Redis, chứa giá trị hiện tại của mỗi feature để tra cứu inference thời gian thực). Vì cả hai store đều được nạp từ cùng một định nghĩa feature, một model được huấn luyện với giá trị lịch sử của offline store sẽ thấy đúng ngữ nghĩa feature đó tại thời điểm inference từ online store — loại bỏ skew bằng thiết kế thay vì bằng quy ước.

Vai trò của data engineer trong ML pipeline phản ánh vai trò của họ trong analytics: tính toán feature đáng tin cậy, không phải huấn luyện model. Xây dựng và vận hành các pipeline tính feature đúng, backfill giá trị lịch sử cho training, và giữ online store luôn cập nhật (thường theo cơ chế streaming cho các feature cần phản ánh hoạt động rất gần đây) chính là công việc data engineering; chọn kiến trúc model và tinh chỉnh nó là công việc thuộc về vai trò machine learning. Phần nội dung ML/MLOps sâu hơn — huấn luyện model, đánh giá, triển khai — nếu có ở nơi khác trong bộ kiến thức này, thì bài này chỉ giới hạn trong nửa serving layer của ranh giới đó.

Các mẫu tiêu thụ và điểm hỏng thường gặp

Các consumer khác nhau của serving layer cần những thứ khác nhau từ data engineer, và việc bỏ bê serving layer sẽ làm hỏng mỗi cái theo một cách đặc trưng:

Consumption patternData engineer cần cung cấp gìĐiểm hỏng thường gặp nếu bị bỏ bê
BI dashboardStar schema được modeling tốt, hiệu năng query nhanh, metric được định nghĩa trong semantic layer dùng chungDashboard chậm, hoặc năm dashboard mâu thuẫn về cùng một metric vì mỗi cái được xây bằng SQL ad-hoc
Reverse ETLBảng mart đáng tin cậy, đã khử trùng lặp, với key ổn định khớp với dữ liệu ở hệ thống đíchDữ liệu sai hoặc cũ bị đẩy vào CRM/công cụ marketing, âm thầm làm hỏng hệ thống vận hành mà đội nghiệp vụ dựa vào
ML feature storeFeature được tính giống hệt cho training (offline) và inference (online), refresh theo nhịp/độ trễ đã biếtTraining-serving skew — model suy giảm hiệu năng trong production dù chấm điểm tốt offline, và nguyên nhân vô hình nếu không so sánh trực tiếp giá trị feature offline và online
Ad-hoc analyst queryCác bảng sạch, tài liệu hóa, hiệu năng tốt, đặt tên và lineage rõ ràngAnalyst tốn thời gian đảo ngược các bảng raw, hoặc rút ra kết luận sai từ cột/join không được tài liệu hóa

Best Practices

Tài liệu tham khảo

Part of the Data Engineer Roadmap knowledge base.

Overview

Every note so far in this knowledge base has been about getting data into a well-shaped place: ingesting it (./03-data-sources-and-ingestion.md), modeling it into a warehouse (./06-data-modeling-and-warehousing.md), and moving it through pipelines (./08-etl-elt-and-data-pipelines.md). None of that work pays off until someone — or something — actually consumes the result. The serving layer is the final stage of the data engineering lifecycle: the point where modeled, trustworthy data is exposed to humans through dashboards and self-service BI tools, to other systems through APIs and reverse ETL, and to machine learning models through feature stores. A data engineer’s job is not complete when a dbt run succeeds; it is complete when a sales rep sees the right number in Salesforce, an executive trusts the revenue chart in a dashboard, or a fraud model scores a transaction in real time using features that were computed correctly.

This note is deliberately “last mile” in focus. It does not re-explain how to model a warehouse or build a pipeline — it explains what happens after that work is done: how BI tools like Tableau, Looker, and Power BI turn a well-modeled warehouse into fast, trustworthy dashboards; why a semantic layer is necessary to stop five dashboards from showing five different numbers for “revenue”; where lightweight tools like Streamlit fit relative to full BI platforms; how data engineers enable analysts to do deeper analysis without doing that analysis themselves; the data engineering discipline behind reliable A/B testing; and the specific serving-layer problem — training-serving skew — that feature stores exist to solve.

Fundamentals

The serving layer as the last stage of the lifecycle

It’s useful to think of the data engineering lifecycle as ending in a fan-out rather than a single destination. Once data is extracted, stored, and transformed into clean, modeled tables, it branches out to wherever it creates value:

Serving the modeled warehouse
Modeled warehousemarts
  • humans explore visually
    BI toolTableau, Looker, Power BI
  • operational SaaS tools
    Reverse ETL
  • ML training & inference
    Feature store
  • analysts, data scientists
    Ad-hoc SQL / notebooks

Each of these consumption patterns has different requirements for freshness, latency, and query shape, and each fails differently when the data engineer treats “the model is built” as the finish line. A mart that’s perfect for a nightly BI refresh might be far too slow, or far too stale, for a feature store powering real-time inference. Designing the serving layer well means understanding, for each consumer, not just what data they need but how fast, how often, and in what shape they need to get it — and that understanding has to happen before the pipeline is built, not after a dashboard turns out to be unusably slow.

Business Intelligence (BI) tools

BI tools exist to let people who don’t write SQL — or who don’t want to write it every time — explore data visually and build dashboards without engineering help. The three dominant players work from the same underlying idea (connect to a warehouse, model or map its tables, let users drag fields onto a canvas to build charts) but differ in philosophy:

ToolModelNotable strength
TableauConnects to a warehouse or extracts data into its own in-memory engine (Hyper)Best-in-class visual exploration and ad-hoc “drag and drop” analysis; strong for analysts who want to interrogate data freely
LookerQuery-pushdown — always queries the live warehouse, never extracts dataLookML, a version-controlled semantic modeling layer (below) that centralizes metric and dimension definitions
Power BIConnects to a warehouse or imports data into its own columnar engine (VertiPaq)Deep integration with the Microsoft ecosystem (Excel, Azure, Teams); DAX for calculated measures

What all three have in common is that they are only as good as the data underneath them. A BI tool is a lens, not a fix — it renders whatever the warehouse gives it, at whatever speed the warehouse can answer a query. This is why the earlier note on data modeling matters so directly here: a well-modeled warehouse — specifically, a star schema (./06-data-modeling-and-warehousing.md) with clean fact and dimension tables — is what makes BI tools feel fast and trustworthy, while a warehouse full of ungoverned raw tables and ad-hoc joins is what makes them feel slow and confusing.

Two concrete mechanisms explain why the model matters this much:

Self-service exploration and its limits

The promise of BI tools is self-service: a marketing manager builds their own chart of campaign performance without filing a ticket with the data team. This genuinely works when the warehouse is well modeled, because self-service exploration is really just “let non-engineers combine pre-defined, trustworthy building blocks (facts, dimensions, metrics) themselves,” rather than “let anyone write arbitrary SQL against raw data.” The data engineer’s job is to build and maintain those building blocks; the BI tool and the semantic layer are what make combining them safe for people without a data engineering background.

Key Concepts

The semantic layer: one metric, defined once

The single most important idea in this note is the semantic layer: a governed layer, sitting between the warehouse and every BI tool or dashboard, where business metrics and dimensions are defined exactly once — “active user,” “revenue,” “churned customer” — and every downstream consumer references that single definition instead of recalculating it themselves.

The problem the semantic layer solves is a familiar one to anyone who has worked at a company with more than one dashboard: five different dashboards show five different numbers for “revenue,” because five different people wrote five different SQL queries, each with a slightly different assumption. One analyst’s “revenue” includes tax; another’s excludes refunds; a third joins on order_date while a fourth joins on shipped_date. None of them are lying — they just each made an independent, reasonable-sounding choice, and there was no single place to look up the “official” definition. The result is a credibility crisis: leadership stops trusting dashboards, and every number gets re-litigated in meetings instead of driving decisions.

A semantic layer fixes this structurally rather than through discipline or memos. The metric is defined once, typically as code:

# Example: a metric defined once in a semantic layer (dbt Semantic Layer / MetricFlow style)
metrics:
  - name: revenue
    label: "Revenue"
    description: "Net revenue recognized: gross order amount minus refunds, excluding tax."
    type: simple
    type_params:
      measure: net_order_amount
    filter: |
      {{ Dimension('order__status') }} = 'completed'
# Example: the same idea expressed in LookML, Looker's semantic modeling layer
measure: revenue {
  type: sum
  sql: ${TABLE}.net_order_amount ;;
  filters: [order.status: "completed"]
  description: "Net revenue recognized: gross order amount minus refunds, excluding tax."
}

Every dashboard, every ad-hoc query routed through the semantic layer, and every BI tool connected to it now inherits the same revenue — change the definition once (say, finance decides revenue should now be recognized on shipped_date instead of order_date) and every consumer updates consistently, instead of someone having to hunt down and edit twelve separate SQL queries scattered across dashboards nobody remembers building.

LookML deserves specific mention here because it was one of the earliest widely-adopted implementations of this idea: instead of each Looker dashboard containing its own SQL, LookML defines dimensions and measures once, in version-controlled .lkml files, and every Looker “Explore” and dashboard is generated from that shared model. The more recent dbt Semantic Layer (built on MetricFlow) generalizes the same idea outside of any single BI tool — metrics are defined once in the dbt project alongside the models they’re built from, and any BI tool with a semantic layer integration (not just one vendor’s) can query them consistently. The specific tool matters less than the principle: metric definitions belong in a governed, version-controlled layer, not scattered across dashboard-specific SQL.

Streamlit and lightweight internal apps

Not every internal data need justifies the cost — in licensing, setup, and governance overhead — of a full BI platform. Streamlit (and similar frameworks like Gradio or Dash) lets a data engineer or analyst turn a Python script into an interactive web app in a few dozen lines, without touching HTML, CSS, or JavaScript:

import streamlit as st
import pandas as pd

df = pd.read_sql("select * from fct_orders", con=warehouse_connection)

st.title("Orders Dashboard")
region = st.selectbox("Region", df["region"].unique())
filtered = df[df["region"] == region]

st.metric("Total Revenue", f"${filtered['amount_usd'].sum():,.2f}")
st.bar_chart(filtered.groupby("order_month")["amount_usd"].sum())

Its niche relative to Tableau, Looker, or Power BI is narrow but real: quick internal tools for a small audience — a one-off exploration app for a data science team, an internal QA tool for reviewing pipeline output, a prototype dashboard before deciding whether a metric deserves a permanent home in the real BI stack. What it deliberately doesn’t provide is what a full BI platform is built for: enterprise governance, row-level security, a shared semantic layer, scheduled distribution to hundreds of business users, or a polished self-service experience for non-technical staff. The rule of thumb: reach for Streamlit when the audience is small, technical, and internal, and reach for the BI platform when the audience is broad, non-technical, and needs metrics that agree with every other dashboard in the company.

Data analytics practice: what analysts do with what engineers build

It’s worth being precise about the division of labor implied by everything above. Descriptive analytics — what happened — is largely a BI-tool exercise: it answers questions like “what was revenue last quarter” or “which region grew fastest,” and it’s exactly the kind of question a well-modeled warehouse and a semantic layer are built to answer quickly and consistently. Beyond that sits deeper analysis: diagnostic analytics (why did it happen), and work that blends into data science — cohort analysis, statistical testing, causal inference, forecasting.

The data engineer’s role in this deeper work is enabling, not performing. A data engineer does not typically run the regression or design the cohort analysis; a data engineer makes sure the pipeline that feeds that analysis produces clean, well-documented, performant data models, so the analyst or data scientist can spend their time on the actual analytical question instead of on data archaeology — chasing down why a join produces duplicate rows, or why a column’s meaning changed silently three months ago. The clearest sign of a healthy handoff is that analysts spend the overwhelming majority of their time asking and answering business questions, and only rarely need to go digging in raw source tables because something in the modeled layer doesn’t add up.

A/B testing infrastructure

Experimentation is one of the sharpest examples of “the data engineering matters even though the interesting question is a statistics question.” An A/B test is only as trustworthy as the events feeding it, and there are several specifically engineering failure modes that can silently invalidate an otherwise well-designed experiment:

The data engineering ask here is narrow but non-negotiable: an event pipeline (./08-etl-elt-and-data-pipelines.md, ./11-streaming-and-realtime-data.md) that captures assignment and outcome events with strong delivery guarantees, stable identifiers that survive the length of the experiment, and monitoring that catches SRM and other pipeline anomalies automatically — because a downstream statistician cannot correct for missing or mis-joined data no matter how sophisticated the significance test.

Feature stores and training-serving skew

Machine learning consumption of the serving layer has a problem BI dashboards don’t: the same feature — say, “number of purchases by this customer in the last 30 days” — has to be computed identically in two very different contexts. During training, it’s computed in bulk over historical data, often with a batch SQL or Spark job. During inference (serving live predictions), it has to be computed for a single entity, right now, often with millisecond latency budgets, sometimes from a completely different code path or even a different team’s service. If those two computations drift apart even slightly — a different time-zone handling, an off-by-one in the lookback window, a slightly different definition of “purchase” — the model sees different feature values in production than it was trained on, and its accuracy silently degrades. This is training-serving skew, and it’s one of the most common causes of a model that scored well offline but performs poorly in production.

A feature store (Feast, Tecton, or a cloud-native offering like SageMaker Feature Store) is the specialized serving layer built to close this gap. It computes a feature once, from a defined transformation, and stores it in two forms kept consistent with each other: an offline store (typically the warehouse or a lake, holding historical feature values for training) and an online store (a low-latency key-value store, typically Redis-backed, holding the current value of each feature for real-time inference lookups). Because both stores are populated from the same feature definition, a model trained against the offline store’s historical values sees the same feature semantics at inference time from the online store — eliminating skew by construction rather than by convention.

The data engineer’s role in the ML pipeline mirrors their role in analytics: reliable feature computation, not model training. Building and operating the pipelines that compute features correctly, backfill historical values for training, and keep the online store fresh (often on a streaming basis for features that need to reflect very recent activity) is squarely data engineering work; choosing the model architecture and tuning it is squarely a machine learning role. Where deeper ML/MLOps material — model training, evaluation, deployment — exists elsewhere in this knowledge base, this note stays scoped to the serving-layer half of that boundary.

Consumption patterns and their failure modes

Different consumers of the serving layer need different things from the data engineer, and neglecting the serving layer breaks each of them in a characteristic way:

Consumption patternWhat the data engineer must provideCommon failure mode if neglected
BI dashboardA well-modeled star schema, fast query performance, metrics defined in a shared semantic layerDashboards are slow, or five dashboards disagree on the same metric because each was built with ad-hoc SQL
Reverse ETLA trustworthy, deduplicated mart table with a stable key matching the destination system’s recordsWrong or stale data gets pushed into a CRM/marketing tool, silently corrupting the operational system business teams rely on
ML feature storeFeatures computed identically for training (offline) and inference (online), refreshed on a known cadence/latencyTraining-serving skew — the model degrades in production despite scoring well offline, and the cause is invisible without comparing offline vs. online feature values directly
Ad-hoc analyst queryClean, documented, performant tables with clear naming and lineageAnalysts waste time reverse-engineering raw tables, or draw wrong conclusions from undocumented columns/joins

Best Practices

References