dbt voor Data Analysts in 2026: Modellering, Testing en Sollicitatievragen

dbt (data build tool) beheersen voor data-analyse — projectstructuur, SQL-modellering, teststrategieën en veelgestelde sollicitatievragen met praktische voorbeelden.

dbt data build tool modellering en testing voor data analysts

dbt (data build tool) heeft zich gevestigd als de standaard transformatielaag in de moderne data stack. Data-analystposities vereisen in 2026 steeds vaker praktische dbt-vaardigheden. Met dbt Core v2.0 in alpha en de stabiele versie v1.12 dekt het framework inmiddels alles — van SQL-modellering tot geautomatiseerd testen en documentatie — volledig versiebeheerd in Git.

Deze gids behandelt de dbt-projectstructuur, modelleringspatronen, teststrategieën en de sollicitatievragen die het vaakst gesteld worden in gesprekken voor data-analyst- en data-engineering-posities.

dbt in de ELT-pipeline

dbt verzorgt de T (Transform) in ELT. Ruwe data komt via ingestietools (Fivetran, Airbyte) in het warehouse terecht, waarna dbt deze transformeert tot schone, geteste en gedocumenteerde modellen die klaar zijn voor analyse. In tegenstelling tot traditionele ETL draaien de transformaties rechtstreeks in het warehouse met SQL.

dbt-projectstructuur: Staging, Intermediate en Marts

Een goed georganiseerd dbt-project volgt een gelaagde architectuur. Elke laag heeft een specifieke verantwoordelijkheid, en deze scheiding voorkomt onoverzichtelijke SQL die onmogelijk te onderhouden wordt.

De standaardconventie gebruikt drie lagen:

  • Staging — dunne modellen die ruwe brondata hernoemen, type-converteren en opschonen. Per brontabel bestaat precies één stagingmodel.
  • Intermediate — bedrijfslogica die stagingmodellen koppelt en aggregeert. Dit zijn interne bouwstenen.
  • Marts — eindmodellen die geconsumeerd worden door dashboards, rapporten en analisten. Elke mart vertegenwoordigt een bedrijfsentiteit of metriek.
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

Het stagingmodel verzorgt typeconversies en hernoemingen. Het mart-model bevat de bedrijfslogica. Deze scheiding betekent dat een wijziging in het bronschema slechts de aanpassing van één enkel stagingmodel vereist — niet van elke downstream query.

Materialisaties: De juiste strategie kiezen

dbt ondersteunt vier kernmaterialisaties die bepalen hoe modellen in het warehouse worden opgeslagen. De verkeerde keuze leidt tot trage queries of onnodige rekenkosten.

| Materialisatie | Toepassingsgebied | Rebuild-gedrag | |---------------|-------------------|----------------| | view | Lichte stagingmodellen, lage queryfrequentie | Wordt bij elke run als SQL view opnieuw aangemaakt | | table | Mart-modellen die vaak door dashboards worden bevraagd | Volledige tabelopbouw bij elke run | | incremental | Grote feitentabellen (events, logs) | Voegt alleen nieuwe rijen toe/mergt | | ephemeral | Herbruikbare CTE's, nooit direct bevraagd | Wordt inline als subquery gecompileerd |

Incrementele modellen verdienen extra aandacht omdat ze het meest voorkomende performanceknelpunt aanpakken — het verwerken van miljarden rijen bij elke run.

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

De macro is_incremental() controleert of het model al bestaat. Bij de eerste run verwerkt dbt alle data. Bij volgende runs worden alleen nieuwe rijen verwerkt — een job van twee uur wordt zo teruggebracht tot enkele minuten.

Datakwaliteit testen met dbt

Testen in dbt werkt op twee niveaus: schematests gedefinieerd in YAML en aangepaste tests geschreven in SQL. Beide worden uitgevoerd met dbt test en laten de pipeline falen wanneer overtredingen worden gevonden.

Schematests dekken de meest voorkomende datakwaliteitscontroles zonder SQL te hoeven schrijven:

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

Voor complexe validatielogica die YAML niet kan uitdrukken, vullen aangepaste singulaire tests het gat:

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

Elke rij die door een singulaire test wordt geretourneerd, duidt op een fout. Dit patroon detecteert datacorruptie, upstream-bugs en logicafouten voordat ze de dashboards bereiken.

Klaar om je Data Analytics gesprekken te halen?

Oefen met onze interactieve simulatoren, flashcards en technische tests.

Jinja en Macro's: Herbruikbare SQL-logica

dbt gebruikt Jinja-templating om SQL dynamisch te maken. De twee belangrijkste functies zijn ref() voor modelverwijzingen en source() voor verwijzingen naar ruwe data. Daarnaast elimineren macro's repetitieve SQL-patronen in het hele project.

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') }}

De macro wordt tijdens de build gecompileerd naar standaard SQL. Deze aanpak garandeert consistente valutaconversielogica in elk model dat met monetaire waarden werkt — een enkele wijziging in de macro werkt automatisch door overal.

dbt-sollicitatievragen voor Data Analysts

Interviewers die dbt-kennis toetsen, richten zich op praktisch begrip van het gereedschap in plaats van uit het hoofd geleerde definities. De volgende vragen komen regelmatig terug in gesprekken voor data analytics-posities.

V1: Wat is het verschil tussen ref() en source()?

source() verwijst naar ruwe tabellen die door ingestietools worden geladen en gedefinieerd zijn in een sources.yml-bestand. ref() verwijst naar andere dbt-modellen. Het gebruik van ref() bouwt de DAG (directed acyclic graph) op die dbt gebruikt om de uitvoeringsvolgorde te bepalen en de data-lineage te volgen. Het hardcoden van tabelnamen in plaats van ref() doorbreekt de lineage-tracking en voorkomt dat dbt modellen in de juiste volgorde uitvoert.

V2: Wanneer moet een incrementeel model worden gebruikt in plaats van een tabel?

Incrementele modellen zijn geschikt wanneer de brondata append-only is of een betrouwbare tijdstempelkolom heeft, en de tabel groot genoeg is dat volledige herbouwen te langzaam of te duur is. Eventtabellen, logdata en tijdreeksdata zijn typische kandidaten. Kleine dimensietabellen behoren als table-materialisatie te blijven omdat de complexiteit van incrementele logica niet gerechtvaardigd is.

V3: Hoe gaat dbt om met Slowly Changing Dimensions (SCD Type 2)?

dbt-snapshots implementeren SCD Type 2-tracking. Een snapshot bewaakt een brontabel en registreert wijzigingen door de kolommen dbt_valid_from en dbt_valid_to toe te voegen. Er bestaan twee strategieën: timestamp (gebruikt een updated_at-kolom) en check (vergelijkt kolomwaarden direct). Snapshots worden uitgevoerd met dbt snapshot, apart van dbt run.

V4: Het staging/intermediate/marts-patroon uitleggen.

Stagingmodellen schonen ruwe brondata op en hernoemen deze — één model per brontabel, geen joins, geen aggregaties. Intermediate-modellen bevatten de bedrijfslogica: joins, filters en berekeningen die als bouwstenen dienen. Mart-modellen zijn de eindresultaten die door analisten en dashboards worden geconsumeerd. Deze gelaagdheid zorgt ervoor dat elk model een enkele verantwoordelijkheid heeft en dat wijzigingen in het bronschema alleen stagingmodellen raken.

V5: Hoe verschillen aangepaste tests van schematests?

Schematests worden gedeclareerd in YAML en dekken standaardcontroles: unique, not_null, accepted_values en relationships. Aangepaste singulaire tests zijn SQL-queries in de tests/-directory — elke geretourneerde rij duidt op een fout. Aangepaste generieke tests zijn geparametriseerde macro's die hergebruikt kunnen worden over modellen heen, net als schematests. Schematests worden gebruikt voor gangbare constraints, singulaire tests voor complexe bedrijfsregels zoals "de omzet mag nooit negatief zijn."

dbt Best Practices voor productieprojecten

dbt-projecten in productie die uitgroeien voorbij een handvol modellen vereisen consistente conventies. Deze praktijken voorkomen de technische schuld die zich ophoopt wanneer meerdere analisten aan hetzelfde project bijdragen.

Naamconventies houden het project navigeerbaar. Stagingmodellen gebruiken het prefix stg_, intermediate-modellen int_, en feiten-/dimensietabellen fct_ of dim_. Bronspecifieke subdirectories (models/staging/stripe/, models/staging/salesforce/) groeperen gerelateerde modellen.

Documentatie leeft naast de code. Elk model en elke kolom dient een description te hebben in het bijbehorende YAML-bestand. Het uitvoeren van dbt docs generate produceert een doorzoekbare documentatiewebsite met een visuele DAG — onmisbaar voor het inwerken van nieuwe teamleden en het auditen van de data-lineage.

Source-freshness-checks detecteren upstream-fouten voordat ze zich verspreiden:

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

Het commando dbt source freshness controleert of de brondata binnen het verwachte tijdsvenster is bijgewerkt. Een gat van 24 uur in betalingsdata signaleert een ingestiefout die onderzocht moet worden voordat transformaties worden uitgevoerd.

Voor verdiepende SQL-vaardigheden die in dbt-modellen worden toegepast, behandelen de gidsen over SQL window functions en CTE's en geavanceerd SQL voor sollicitatiegesprekken de querypatronen die het vaakst voorkomen in staging- en mart-modellen.

Begin met oefenen!

Test je kennis met onze gespreksimulatoren en technische tests.

Conclusie

  • dbt verzorgt de transformatielaag in ELT-pipelines en voert SQL rechtstreeks uit in het datawarehouse zonder een aparte compute-engine te vereisen
  • Het staging/intermediate/marts-patroon scheidt bronopschoning van bedrijfslogica, waardoor wijzigingen voorspelbaar en geïsoleerd zijn
  • Incrementele materialisaties verminderen de verwerkingstijd voor grote tabellen door alleen nieuwe of bijgewerkte rijen te verwerken
  • Schematests (YAML) dekken standaardconstraints; singulaire tests (SQL) valideren complexe bedrijfsregels
  • Jinja-macro's elimineren herhaalde SQL-logica en waarborgen consistentie over alle modellen
  • Source-freshness-checks detecteren upstream-ingestiefouten voordat ze downstream-modellen beschadigen
  • De sollicitatievoorbereiding dient zich te richten op praktische scenario's — DAG-lineage, materialisatie-afwegingen en teststrategieën — in plaats van uit het hoofd geleerde definities

Begin met oefenen!

Test je kennis met onze gespreksimulatoren en technische tests.

Tags

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

Delen

Gerelateerde artikelen