Datenvalidierung: der vollständige Leitfaden
Die sechs Prüfungen, die die meisten realen Vorfälle abfangen, wo sie laufen sollten, und wie aus Ad-hoc-SQL ein versionierter Data Contract wird, der nach Zeitplan läuft.
· 11 min read
Um Daten zu validieren, formulieren Sie jede Erwartung als Abfrage, die eine Anzahl verletzender Zeilen zurückgibt, führen den gesamten Satz nach jedem Ladevorgang gegen das Dataset aus und lassen die Prüfung fehlschlagen, sobald eine Anzahl einen zuvor vereinbarten Schwellenwert überschreitet. Sechs Prüfungen fangen die überwiegende Mehrheit realer Vorfälle ab: fehlende Werte in Pflichtspalten, doppelte Geschäftsschlüssel, Werte außerhalb einer erlaubten Menge, Zahlen außerhalb eines plausiblen Bereichs, fehlerhaft formatierte Zeichenketten und veraltete Zeilen. Die Prüfungen selbst sind gewöhnliches SQL — schwierig ist, sie dort auszuführen, wo die Daten liegen, sie mit dem Schema synchron zu halten und so zu alarmieren, dass niemand lernt, die Meldungen zu ignorieren. Alles Folgende ist die Maschinerie, um genau das zuverlässig zu tun.
Was Datenvalidierung tatsächlich ist
Drei Dinge werden Validierung genannt, und nur eines davon ist Thema dieses Leitfadens.
Eingabevalidierung findet am Rand einer Anwendung statt: Ein Formular weist eine E-Mail-Adresse ohne @ zurück. Sie ist ein Tor beim Schreiben, Datensatz für Datensatz.
Schemavalidierung prüft die Struktur — hat die Tabelle die Spalten, die der Loader erwartet, in den Typen, die er erwartet? Sie erkennt einen gebrochenen Vertrag zwischen Systemen, nicht fehlerhafte Werte innerhalb eines wohlgeformten.
Datenvalidierung prüft den Inhalt eines bereits existierenden Datasets, in großem Umfang, nachdem es gelandet ist: Wie viele der 4,2 Millionen Zeilen, die wir letzte Nacht geladen haben, brechen eine Zusage, auf die sich jemand verlässt?
Diese Unterscheidung bestimmt die Form der Lösung. Sie weisen keine Zeilen zurück; die Zeilen sind bereits da. Sie messen nach einem Zeitplan und entscheiden, was aus der Messung folgt. Ein Validierungslauf erzeugt eine Zahl je Regel, ein Bestehen oder Scheitern je Regel und eine Historie — und genau das macht aus „die Daten sehen komisch aus" den Satz „die NULL-Quote auf customer_id ist am vergangenen Dienstag um 04:12 Uhr von 0,02 % auf 11 % gesprungen". Wenn Sie die Definition für sich genommen suchen, inklusive der Abgrenzung von Testing, Observability und Bereinigung, beginnen Sie bei was Datenvalidierung ist und kommen für die Mechanik hierher zurück.
Die sechs Prüfungen, die jedes Dataset braucht
Jede Prüfung hat dieselbe Form. Zählen Sie die Zeilen, die gegen die Erwartung verstoßen, und vergleichen Sie die Anzahl mit einem Schwellenwert:
SELECT count(*) AS violations
FROM sales.orders
WHERE order_id IS NULL;
Das ist das gesamte Muster. Eine Regel ist ein Prädikat, eine Anzahl und ein Schwellenwert — und die sechs, auf die es ankommt, sind schlicht sechs Prädikate:
| Prüfung | Dimension | Fängt ab | Prädikat |
|---|---|---|---|
| Vollständigkeit | Vollständigkeit | Eine Spalte, die nicht mehr befüllt wird | col IS NULL |
| Eindeutigkeit | Eindeutigkeit | Wiederholungsläufe, erneute Ladevorgänge, doppelt gezählter Umsatz | GROUP BY key HAVING count(*) > 1 |
| Gültigkeit | Konformität | Ein neuer Enum-Wert, von dem Ihnen niemand erzählt hat | col NOT IN ('a', 'b', 'c') |
| Wertebereich | Genauigkeit | Einheitenfehler, Währungsfehler, negative Mengen | col < 0 OR col > 100000 |
| Format | Konformität | Fehlerhafte Bezeichner, abgeschnittene Codes | col NOT LIKE / !~ pattern |
| Freshness | Aktualität | Eine Pipeline, die stillschweigend nicht mehr läuft | max_ts < now() - interval |
Zwei Ergänzungen verdienen sich auf den meisten Tabellen ihren Platz: eine rowCount-Regel auf Tabellenebene, weil ein leeres Ergebnis nach einem Ladevorgang ein eigener und sehr häufiger Fehlerfall ist, und eine Prüfung der referenziellen Integrität auf Fremdschlüsseln, weil unvollständige Backfills Waisen hinterlassen, die Inner Joins stillschweigend verwerfen.
Die NULL-Falle, in die jeder einmal tappt
Schreiben Sie die Gültigkeitsprüfung so, wie sie oben steht, und sie wird Sie anlügen:
-- Wrong: nulls disappear from the count.
WHERE status NOT IN ('pending', 'paid', 'shipped', 'refunded')
-- Right:
WHERE status IS NOT NULL
AND status NOT IN ('pending', 'paid', 'shipped', 'refunded')
NULL NOT IN (...) ergibt in jeder SQL-Engine NULL, nicht true. Ohne die Absicherung meldet eine Spalte, die zu 90 % NULL ist, perfekte Konformität. Das ist das mit Abstand häufigste falsche „bestanden" in handgeschriebenem Datenqualitäts-SQL, und es lohnt sich, jede geerbte Regel darauf abzuklopfen.
Wo die Prüfungen laufen sollten
Lassen Sie sie im Data Warehouse laufen, über eine Nur-Lese-Verbindung, und bewegen Sie die Zeilen nie.
Daten herauszuziehen, um sie zu validieren, ist aus drei Gründen der falsche Reflex: Es ist langsam, es kopiert sensible Zeilen in ein zweites System mit einer zweiten Sicherheitsprüfung, und es skaliert nicht — eine Prüfung, die eine Faktentabelle mit einer Milliarde Zeilen exportieren muss, wird nicht stündlich laufen. Die Aggregation in die Engine hinunterzudrücken bedeutet, dass jede Prüfung ein einziges SELECT ist, das eine Zahl zurückgibt — genau die Last, für die jedes Data Warehouse gebaut ist.
Der Rechtesatz ist wirklich minimal: Verbinden auf der Datenbank, Lesen des Schemakatalogs, SELECT auf den geprüften Tabellen. Sonst nichts. Wenn ein Validierungswerkzeug Schreibzugriff verlangt, fragen Sie nach dem Warum. Richten Sie die Verbindung auf ein Read Replica, wo es eines gibt — es handelt sich um Aggregat-Scans ohne Konsistenzanforderung jenseits von „aktuell" — und setzen Sie ein Abfrage-Timeout, damit ein nicht indizierter Scan keine Verbindung eine Stunde lang blockiert.
Manuelles SQL, ein Framework oder ein verwalteter Dienst
Es gibt drei ehrliche Wege, und der richtige hängt davon ab, wie viele Datasets Sie haben und wer die Regeln lesen können muss.
| Ansatz | Gut in | Scheitert, wenn |
|---|---|---|
| Handgeschriebenes SQL im Cron | Null Einrichtung, volle Kontrolle, kein neuer Anbieter | Regeln vom Schema abdriften; niemand weiß, welche Skripte noch laufen |
| Ein Framework (dbt-Tests, Great Expectations, Soda) | Versionskontrolliert, läuft in Ihrer Pipeline | Regeln an das Format dieses Runners gebunden sind; nur abgedeckt ist, was dem Werkzeug gehört |
| Ein verwalteter Validierungsdienst | Zeitplanung, Historie, Alarmierung und eine Oberfläche, die auch Nicht-Entwickler lesen | Sie einem Anbieter eine Verbindung anvertrauen und das Regelformat üblicherweise seines ist |
Der Fehlermodus des ersten Wegs ist Entropie: Innerhalb eines Jahres haben Sie vierzig SQL-Dateien, sechs davon referenzieren gelöschte Spalten, und niemand traut sich, eine davon zu entfernen. Der Fehlermodus des zweiten ist Reichweite — dbt-Tests sind ausgezeichnet, decken aber nur Modelle ab, die dbt baut, und sie laufen, wenn dbt läuft. Der Fehlermodus des dritten ist Lock-in, und genau deshalb gibt es den nächsten Abschnitt.
Nichts davon schließt einander aus. Teams, die das gut lösen, legen schnelle, billige Assertions in die Pipeline, wo sie einen Build scheitern lassen, und bewahren die dauerhaften Zusagen dort auf, wo sie geprüft und überwacht werden — unabhängig davon, welches Werkzeug die Tabelle heute geschrieben hat.
Data Contracts: die Erwartungen versionieren, nicht die Skripte
Die dauerhafte Antwort auf Regel-Entropie besteht darin, Prüfungen nicht mehr als Code zu schreiben, sondern als Dokument — eine Erklärung dessen, was das Dataset zusagt, abgelegt neben Ihrem übrigen Quellcode, im Pull Request geprüft und von welchem Runner auch immer ausgeführt. Dieses Dokument ist ein Data Contract.
Der Open Data Contract Standard ist die offene Spezifikation, um einen solchen zu schreiben. Er ist YAML, er wird im Rahmen des Bitol-Projekts der Linux Foundation entwickelt statt von einem Anbieter, und ein minimaler Contract für die obigen Prüfungen sieht so aus:
apiVersion: v3.0.0
kind: DataContract
info:
title: orders
version: 1.0.0
owner: data-platform
schema:
- name: orders
physicalName: orders
physicalType: table
properties:
- name: order_id
logicalType: string
required: true
primaryKey: true
quality:
- rule: nullCount
dimension: completeness
severity: error
mustBe: "0"
- rule: duplicateCount
dimension: uniqueness
severity: error
mustBe: "0"
- name: status
logicalType: string
quality:
- rule: validValues
dimension: conformity
severity: error
mustBe: "['pending', 'paid', 'shipped', 'refunded']"
- name: total_amount
logicalType: number
quality:
- rule: between
dimension: accuracy
severity: error
mustBe: "[0, 100000]"
- name: created_at
logicalType: timestamp
quality:
- rule: freshness
dimension: timeliness
severity: error
mustBe: "<= 24h"
quality:
- rule: rowCount
dimension: completeness
severity: warning
mustBe: "> 0"
Drei Eigenschaften machen den Aufwand lohnend.
Er ist portabel. nullCount bedeutet überall dasselbe; der Runner kompiliert es in den Dialekt der jeweiligen Engine. Ein Wechsel des Data Warehouse ist damit keine Regelmigration mehr.
Er ist prüfbar. Eine Schwellenwertänderung ist ein Diff mit einem Autor und einer Begründung. Ob eine Grenze verschoben wurde, weil sich das Geschäft geändert hat oder weil jemand den Alarm satthatte, wird damit nachvollziehbar — was es in einer Anbieteroberfläche nie ist.
Er gehört Ihnen. Regeln, die in einem offenen Standard geschrieben sind, sind kein Vermögenswert desjenigen, der sie heute ausführt.
Catalyst setzt direkt auf ODCS auf: Das YAML ist das Speicherformat und nicht die Darstellung einer Datenbankzeile. Eine im visuellen Builder bearbeitete Regel erzeugt deshalb einen einzeiligen Diff, und der im Pull Request geprüfte Contract ist Byte für Byte derselbe, der ausgeführt wird.
Zeitplanung und Alarmierung
Zwei Regeln, beide auf die harte Tour gelernt.
Lösen Sie aus dem Ladevorgang aus, nicht nach der Uhr. Eine Tagestabelle, die um 06:00 Uhr validiert wird, während das ELT um 06:40 Uhr fertig wird, scheitert jeden Morgen aus einem Grund, der nichts mit Qualität zu tun hat. Passen Sie den Takt an die Daten an: stündliche Freshness auf einer Streaming-Tabelle, ein Lauf nach dem nächtlichen Batch für alles andere. Prüfungen häufiger laufen zu lassen, als sich die Daten ändern, erzeugt Rauschen — und auf nutzungsbasiert abgerechneten Data Warehouses eine Rechnung.
Alarmieren Sie bei Übergängen, nicht bei Zuständen. „Orders hat angefangen zu scheitern" ist handlungsleitend. „Orders scheitert immer noch", stündlich wiederholt, ist der Weg, auf dem ein Channel stummgeschaltet wird — und ein stummgeschalteter Channel ist schlimmer als gar keine Alarmierung, weil er wie Abdeckung aussieht.
Nutzen Sie die Severity, um die beiden Regelpopulationen zu trennen. Reservieren Sie error für Prüfungen, die einen nachgelagerten Konsumenten tatsächlich blockieren sollten: eine Dashboard-Aktualisierung, einen Reverse-ETL-Abgleich, einen Finanzbericht. Alles andere — Musterprüfungen auf manuell erfassten Feldern, Drift in der Zeilenzahl, Auffälligkeiten in der Verteilung — gehört auf warning, wo es eine Trendlinie ist und kein Pager-Alarm.
Welche Datasets zuerst validieren?
Sie können nicht alles validieren, und der Versuch ist der Weg, auf dem das Projekt stirbt. Ordnen Sie nach Schadensradius:
- Alles, was in eine Zahl fließt, die eine Führungskraft liest. Umsatz, Personalbestand, Pipeline. Eine falsche Zahl kostet hier Glaubwürdigkeit, deren Wiederaufbau Monate dauert.
- Alles, was in eine automatisierte Entscheidung fließt. Preisgestaltung, Kreditlimits, ML-Features, Reverse-ETL in ein CRM. Diese Systeme handeln auf Basis schlechter Daten, bevor ein Mensch sie sieht.
- Alles mit einem externen Konsumenten. Ein Partner-Feed oder eine regulatorische Meldung hat Fehlerkosten, die Sie nicht kontrollieren.
- Die Joins im Kern Ihres Modells. Die Dimensionstabellen, an die alles joint und bei denen ein verwaister Schlüssel stillschweigend Zeilen aus jeder nachgelagerten Abfrage entfernt.
Beginnen Sie mit fünf bis zehn Regeln auf einer solchen Tabelle statt mit drei Regeln auf vierzig. Eine Abdeckung, die überall flach ist, sagt Ihnen nichts; eine Abdeckung, die auf den entscheidenden Tabellen tief geht, fängt genau die Vorfälle ab, von denen Sie sonst von jemand anderem erfahren.
Lesen Sie danach den Leitfaden zu Ihrer Engine — die sechs Prüfungen sind universell, das SQL, die Fallen und das Kostenmodell sind es nicht:
- PostgreSQL — echte Regex, ehrliche NULL-Semantik und das Risiko, die transaktionale Primärdatenbank zu scannen
- MySQL — implizite Typumwandlung, Nulldaten und collationsabhängige Gleichheit
- SQL Server — kein Regex-Operator,
COUNT_BIGund Collation-Fallen - BigQuery — Validierung ist zuerst ein Kostenproblem; Partitionsfilter sind das ganze Spiel
- Amazon Redshift — nicht erzwungene Constraints, denen der Planner trotzdem glaubt, plus WLM-Konkurrenz
- Microsoft Fabric — Entra-ID-Authentifizierung, eine schmalere T-SQL-Oberfläche und Verzögerungen bei den Endpunkt-Metadaten
- CSV-, JSON- und Excel-Dateien — wo die meisten Defekte Parsing-Probleme sind und keine Regelverstöße
Catalyst setzt genau den beschriebenen Ablauf um — Schema importieren, einen Basisvertrag vorschlagen, jede Regel in das SQL Ihrer Engine kompilieren, sie nach Zeitplan ausführen und die pass/warn/fail-Historie je Regel verfolgen — über all diese Verbindungen hinweg, mit einem kostenlosen Plan, um es an einem Dataset auszuprobieren (PostgreSQL und MySQL), bevor Sie sich festlegen (Preise).
Häufig gestellte Fragen
Was gilt als Datenvalidierungsprüfung?
Eine Datenvalidierungsprüfung ist eine vereinbarte Erwartung an den Inhalt eines Datasets, ausgedrückt als Abfrage, die eine Anzahl verletzender Zeilen zurückgibt — keine fehlenden Werte in einer Pflichtspalte, keine doppelten Schlüssel, Werte innerhalb einer erlaubten Menge oder eines plausiblen Bereichs, korrekt formatierte Zeichenketten oder Zeilen, die aktuell genug sind, um nützlich zu sein. Die Prüfung scheitert, wenn diese Anzahl einen von Ihnen vorab gesetzten Schwellenwert überschreitet. Anders als die Eingabevalidierung läuft sie in großem Umfang gegen Daten, die bereits gelandet sind.
Was sind die wichtigsten Arten von Datenvalidierungsprüfungen?
Sechs decken die meisten realen Vorfälle ab: Vollständigkeit (NULL-Werte in Pflichtspalten), Eindeutigkeit (doppelte Geschäftsschlüssel), Gültigkeit (Werte außerhalb einer erlaubten Menge), Genauigkeit (Zahlen außerhalb eines plausiblen Bereichs), Konformität (Zeichenketten, die ein vorgeschriebenes Format verfehlen) und Aktualität (veraltete Zeilen oder Partitionen). Zeilenzahlen auf Tabellenebene und referenzielle Integrität zwischen Tabellen sind die beiden häufigsten Ergänzungen.
Muss ich SQL schreiben, um Daten zu validieren?
Für die Standardprüfungen nicht. Wenn Sie die Erwartung deklarieren — Pflichtfeld, eindeutig, erlaubte Werte, Zahlenbereich, Muster, maximales Alter, Fremdschlüssel —, kann ein Runner sie in das korrekte SQL Ihrer Engine kompilieren, was zugleich die Dialektunterschiede und die NULL-Fallen beseitigt. Handgeschriebenes SQL lohnt sich nur für wirklich maßgeschneiderte Geschäftslogik, über eine eigene SQL-Regel.
Wie oft sollten Datenvalidierungen laufen?
Passen Sie den Zeitplan an den Takt der Daten an und lösen Sie aus dem Job aus, der sie erzeugt, nicht zu einer festen Uhrzeit. Streaming-Tabellen wollen stündliche Freshness-Prüfungen; Batch-Tabellen wollen einen Lauf nach Abschluss des Ladevorgangs. Häufiger zu prüfen, als sich die Daten ändern, erzeugt nur Rauschen — und auf nutzungsbasiert abgerechneten Data Warehouses zusätzlich eine Rechnung.
Ist Datenvalidierung dasselbe wie ein Data Contract?
Nein. Validierung ist das Ausführen der Prüfungen; ein Data Contract ist das versionierte Dokument, das festhält, wie die Prüfungen lauten sollen. Der Contract trägt außerdem Eigentümerschaft, Beschreibungen und Service Levels — und genau das macht ihn für die Konsumenten der Daten prüfbar und nicht nur für das Team, das die Pipeline geschrieben hat. Ein Standard wie ODCS hält den Contract zwischen verschiedenen Runnern portabel.
Braucht Datenvalidierung Schreibzugriff auf meine Datenbank?
Nein. Jede hier beschriebene Prüfung ist ein SELECT, das eine einzige Zahl zurückgibt. Lesezugriff auf die Tabellen plus die Möglichkeit, den Schemakatalog zu lesen, sind der vollständige Rechtesatz. Wo ein Read Replica oder ein lesbares sekundäres Replikat existiert, richten Sie die Verbindung darauf — die Prüfungen haben keine Konsistenzanforderung jenseits von „aktuell", und sie von der Primärdatenbank wegzunehmen entkräftet den wichtigsten betrieblichen Einwand dagegen, sie häufig auszuführen.