dbt für Data Analysts 2026: Modellierung, Testing und Interviewfragen

dbt (data build tool) für die Datenanalyse beherrschen — Projektstruktur, SQL-Modellierung, Testing-Strategien und typische Interviewfragen mit praktischen Beispielen.

dbt data build tool Modellierung und Testing für Data Analysts

dbt (data build tool) hat sich als Standard-Transformationsschicht im modernen Data Stack etabliert. Data-Analyst-Positionen setzen 2026 zunehmend praktische dbt-Kenntnisse voraus. Mit dbt Core v2.0 in der Alpha-Phase und der stabilen Version v1.12 deckt das Framework inzwischen alles ab — von SQL-Modellierung über automatisiertes Testing bis hin zur Dokumentation — komplett versioniert in Git.

Dieser Leitfaden behandelt die dbt-Projektstruktur, Modellierungsmuster, Testing-Strategien und die Interviewfragen, die in Data-Analyst- und Data-Engineering-Vorstellungsgesprächen am häufigsten gestellt werden.

dbt in der ELT-Pipeline

dbt übernimmt das T (Transform) in ELT. Rohdaten werden über Ingestion-Tools (Fivetran, Airbyte) ins Warehouse geladen, anschließend transformiert dbt sie zu sauberen, getesteten und dokumentierten Modellen, die zur Analyse bereitstehen. Im Gegensatz zu traditionellem ETL laufen die Transformationen direkt im Warehouse — ausschließlich mit SQL.

dbt-Projektstruktur: Staging, Intermediate und Marts

Ein gut organisiertes dbt-Projekt folgt einer geschichteten Architektur. Jede Schicht hat eine klar definierte Verantwortung, und diese Trennung verhindert unübersichtliches SQL, das sich kaum noch warten lässt.

Die Standardkonvention verwendet drei Schichten:

  • Staging — schlanke Modelle, die Rohdaten aus Quellen umbenennen, typisieren und bereinigen. Pro Quelltabelle existiert genau ein Staging-Modell.
  • Intermediate — Geschäftslogik, die Staging-Modelle verbindet und aggregiert. Diese Modelle dienen als interne Bausteine.
  • Marts — finale Modelle, die von Dashboards, Reports und Analysten konsumiert werden. Jeder Mart repräsentiert eine Geschäftsentität oder Kennzahl.
sql
-- models/staging/stripe/stg_stripe__payments.sql
with source as (
    select * from {{ source('stripe', 'payments') }}
),

renamed as (
    select
        id as payment_id,
        amount / 100.0 as amount_usd,  -- Stripe stores cents
        status as payment_status,
        created::timestamp as created_at,
        customer_id
    from source
    where status != 'failed'  -- Filter invalid records early
)

select * from renamed
sql
-- models/marts/finance/fct_monthly_revenue.sql
with payments as (
    select * from {{ ref('stg_stripe__payments') }}
),

monthly as (
    select
        date_trunc('month', created_at) as revenue_month,
        count(*) as total_transactions,
        sum(amount_usd) as gross_revenue,
        sum(case when payment_status = 'refunded' then amount_usd else 0 end) as refunds
    from payments
    group by 1
)

select
    revenue_month,
    total_transactions,
    gross_revenue,
    refunds,
    gross_revenue - refunds as net_revenue  -- Key business metric
from monthly

Das Staging-Modell kümmert sich um Typkonvertierungen und Umbenennungen. Das Mart-Modell enthält die Geschäftslogik. Diese Trennung bedeutet: Eine Änderung im Quellschema erfordert nur die Anpassung eines einzigen Staging-Modells — nicht jeder nachgelagerten Abfrage.

Materialisierungen: Die richtige Strategie wählen

dbt unterstützt vier zentrale Materialisierungen, die bestimmen, wie Modelle im Warehouse persistiert werden. Die falsche Wahl führt entweder zu langsamen Abfragen oder unnötigen Rechenkosten.

| Materialisierung | Anwendungsfall | Rebuild-Verhalten | |-----------------|----------------|--------------------| | view | Leichtgewichtige Staging-Modelle, geringe Abfragefrequenz | Wird bei jedem Lauf als SQL View neu erstellt | | table | Mart-Modelle, die häufig von Dashboards abgefragt werden | Vollständiger Tabellenaufbau bei jedem Lauf | | incremental | Große Faktentabellen (Events, Logs) | Nur neue Zeilen werden hinzugefügt/gemergt | | ephemeral | Wiederverwendbare CTEs, nie direkt abgefragt | Wird inline als Subquery kompiliert |

Inkrementelle Modelle verdienen besondere Aufmerksamkeit, da sie den häufigsten Performance-Engpass adressieren — die Verarbeitung von Milliarden Zeilen bei jedem Lauf.

sql
-- models/marts/product/fct_page_views.sql
{{ config(
    materialized='incremental',
    unique_key='page_view_id',
    incremental_strategy='merge'
) }}

with events as (
    select
        event_id as page_view_id,
        user_id,
        page_url,
        session_id,
        event_timestamp
    from {{ ref('stg_snowplow__events') }}
    where event_type = 'page_view'

    {% if is_incremental() %}
        -- Only process new events since last run
        and event_timestamp > (select max(event_timestamp) from {{ this }})
    {% endif %}
)

select * from events

Das Macro is_incremental() prüft, ob das Modell bereits existiert. Beim ersten Lauf verarbeitet dbt alle Daten. Bei nachfolgenden Läufen werden nur neue Zeilen verarbeitet — ein zweistündiger Job reduziert sich auf wenige Minuten.

Datenqualität mit dbt testen

Das Testen in dbt funktioniert auf zwei Ebenen: Schema-Tests, die in YAML definiert werden, und benutzerdefinierte Tests in SQL. Beide werden mit dbt test ausgeführt und lassen die Pipeline bei Verstößen fehlschlagen.

Schema-Tests decken die gängigsten Datenqualitätsprüfungen ab, ohne SQL schreiben zu müssen:

yaml
# models/staging/stripe/_stripe__models.yml
version: 2

models:
  - name: stg_stripe__payments
    description: "Cleaned payment records from Stripe"
    columns:
      - name: payment_id
        description: "Unique payment identifier"
        tests:
          - unique
          - not_null
      - name: payment_status
        tests:
          - accepted_values:
              values: ['succeeded', 'pending', 'refunded']
      - name: amount_usd
        tests:
          - not_null
          - dbt_utils.expression_is_true:
              expression: ">= 0"  # No negative payments

Für komplexe Validierungslogik, die YAML nicht abbilden kann, füllen benutzerdefinierte singuläre Tests die Lücke:

sql
-- tests/assert_revenue_not_negative.sql
-- This test fails if any month has negative net revenue
select
    revenue_month,
    net_revenue
from {{ ref('fct_monthly_revenue') }}
where net_revenue < 0  -- Should never happen

Jede Zeile, die ein singulärer Test zurückliefert, signalisiert einen Fehler. Dieses Muster erkennt Datenkorruption, Upstream-Bugs und Logikfehler, bevor sie Dashboards erreichen.

Bereit für deine Data Analytics-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

Jinja und Macros: Wiederverwendbare SQL-Logik

dbt nutzt Jinja-Templating, um SQL dynamisch zu gestalten. Die beiden wichtigsten Funktionen sind ref() für Modellverweise und source() für Rohdatenverweise. Darüber hinaus eliminieren Macros repetitive SQL-Muster im gesamten Projekt.

sql
-- macros/cents_to_dollars.sql
{% macro cents_to_dollars(column_name) %}
    ({{ column_name }} / 100.0)::numeric(12, 2)
{% endmacro %}
sql
-- Usage in any model
select
    payment_id,
    {{ cents_to_dollars('amount_cents') }} as amount_usd,
    {{ cents_to_dollars('tax_cents') }} as tax_usd
from {{ source('stripe', 'payments') }}

Das Macro wird zur Build-Zeit in Standard-SQL kompiliert. Dieser Ansatz garantiert eine konsistente Währungsumrechnungslogik in jedem Modell, das monetäre Werte verarbeitet — eine Änderung im Macro wirkt sich überall automatisch aus.

dbt-Interviewfragen für Data Analysts

In Vorstellungsgesprächen zu dbt liegt der Fokus auf dem praktischen Verständnis des Tools, nicht auf auswendig gelernten Definitionen. Die folgenden Fragen tauchen regelmäßig in Interviews für Data Analytics-Positionen auf.

F1: Was ist der Unterschied zwischen ref() und source()?

source() verweist auf Rohtabellen, die von Ingestion-Tools geladen und in einer sources.yml-Datei definiert werden. ref() verweist auf andere dbt-Modelle. Die Verwendung von ref() baut den DAG (Directed Acyclic Graph) auf, den dbt nutzt, um die Ausführungsreihenfolge zu bestimmen und die Datenherkunft (Lineage) zu verfolgen. Hartcodierte Tabellennamen statt ref() unterbrechen die Lineage-Verfolgung und verhindern, dass dbt Modelle in der richtigen Reihenfolge ausführt.

F2: Wann sollte ein inkrementelles Modell anstelle einer Tabelle verwendet werden?

Inkrementelle Modelle eignen sich, wenn die Quelldaten nur angefügt werden (append-only) oder eine zuverlässige Zeitstempelspalte haben, und die Tabelle groß genug ist, dass vollständige Neuaufbauten zu langsam oder zu teuer sind. Eventtabellen, Log-Daten und Zeitreihendaten sind typische Kandidaten. Kleine Dimensionstabellen sollten als table-Materialisierung bleiben, da die Komplexität der inkrementellen Logik den Aufwand nicht rechtfertigt.

F3: Wie behandelt dbt Slowly Changing Dimensions (SCD Typ 2)?

dbt-Snapshots implementieren SCD-Typ-2-Tracking. Ein Snapshot überwacht eine Quelltabelle und zeichnet Änderungen über die Zeit auf, indem die Spalten dbt_valid_from und dbt_valid_to hinzugefügt werden. Zwei Strategien stehen zur Verfügung: timestamp (nutzt eine updated_at-Spalte) und check (vergleicht Spaltenwerte direkt). Snapshots werden mit dbt snapshot separat von dbt run ausgeführt.

F4: Das Staging/Intermediate/Marts-Muster erklären.

Staging-Modelle bereinigen und benennen Rohdaten aus Quellen um — ein Modell pro Quelltabelle, keine Joins, keine Aggregationen. Intermediate-Modelle enthalten die Geschäftslogik: Joins, Filter und Berechnungen, die als Bausteine dienen. Mart-Modelle sind die finalen Ergebnisse, die von Analysten und Dashboards konsumiert werden. Diese Schichtung stellt sicher, dass jedes Modell eine einzige Verantwortung hat und Änderungen am Quellschema nur Staging-Modelle betreffen.

F5: Wie unterscheiden sich benutzerdefinierte Tests von Schema-Tests?

Schema-Tests werden in YAML deklariert und decken Standardprüfungen ab: unique, not_null, accepted_values und relationships. Benutzerdefinierte singuläre Tests sind SQL-Abfragen im Verzeichnis tests/ — jede zurückgegebene Zeile zeigt einen Fehler an. Benutzerdefinierte generische Tests sind parametrisierte Macros, die wie Schema-Tests modellübergreifend wiederverwendet werden können. Schema-Tests eignen sich für gängige Constraints, singuläre Tests für komplexe Geschäftsregeln wie 'Der Umsatz darf niemals negativ sein.'

dbt Best Practices für Produktivprojekte

Dbt-Projekte in der Produktion, die über eine Handvoll Modelle hinauswachsen, erfordern konsistente Konventionen. Diese Praktiken verhindern die technischen Schulden, die sich ansammeln, wenn mehrere Analysten zum selben Projekt beitragen.

Namenskonventionen halten das Projekt navigierbar. Staging-Modelle verwenden das Präfix stg_, Intermediate-Modelle int_, und Fakten-/Dimensionstabellen fct_ bzw. dim_. Quellspezifische Unterverzeichnisse (models/staging/stripe/, models/staging/salesforce/) gruppieren zusammengehörige Modelle.

Dokumentation lebt direkt neben dem Code. Jedes Modell und jede Spalte sollte eine description in der zugehörigen YAML-Datei haben. dbt docs generate erzeugt eine durchsuchbare Dokumentationswebsite mit einem visuellen DAG — unverzichtbar für das Onboarding neuer Teammitglieder und die Prüfung der Datenherkunft.

Source-Freshness-Checks erkennen Upstream-Fehler, bevor sie sich fortpflanzen:

yaml
# models/staging/stripe/_stripe__sources.yml
version: 2

sources:
  - name: stripe
    database: raw
    schema: stripe
    freshness:
      warn_after: {count: 12, period: hour}
      error_after: {count: 24, period: hour}
    loaded_at_field: _fivetran_synced
    tables:
      - name: payments
      - name: customers

Der Befehl dbt source freshness prüft, ob die Quelldaten innerhalb des erwarteten Zeitfensters aktualisiert wurden. Eine 24-stündige Lücke bei Zahlungsdaten signalisiert einen Ingestion-Fehler, der untersucht werden muss, bevor Transformationen ausgeführt werden.

Für vertiefende SQL-Kenntnisse, die in dbt-Modellen eingesetzt werden, behandeln die Leitfäden zu SQL Window Functions und CTEs und fortgeschrittenem SQL für Interviews die Abfragemuster, die in Staging- und Mart-Modellen am häufigsten zum Einsatz kommen.

Fang an zu üben!

Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Fazit

  • dbt übernimmt die Transformationsschicht in ELT-Pipelines und führt SQL direkt im Data Warehouse aus, ohne eine separate Compute-Engine zu benötigen
  • Das Staging/Intermediate/Marts-Muster trennt die Quellenbereinigung von der Geschäftslogik und macht Änderungen vorhersehbar und isoliert
  • Inkrementelle Materialisierungen reduzieren die Verarbeitungszeit für große Tabellen, indem nur neue oder aktualisierte Zeilen verarbeitet werden
  • Schema-Tests (YAML) decken Standardconstraints ab; singuläre Tests (SQL) validieren komplexe Geschäftsregeln
  • Jinja-Macros eliminieren redundante SQL-Logik und gewährleisten Konsistenz über alle Modelle hinweg
  • Source-Freshness-Checks erkennen Upstream-Ingestionsfehler, bevor sie nachgelagerte Modelle verfälschen
  • Die Interviewvorbereitung sollte sich auf praktische Szenarien konzentrieren — DAG-Lineage, Materialisierungs-Tradeoffs und Testing-Strategien — statt auf auswendig gelernte Definitionen

Fang an zu üben!

Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Tags

#dbt
#data-analytics
#sql
#data-modeling
#interview

Teilen

Verwandte Artikel