---
{
  "title": "Das Kahn-Framework auf FHIR anwenden",
  "description": "Was unterscheidet gute FHIR-Daten von schlechten? Die Welt der Gesundheitsdaten hat vor einem Jahrzehnt ein präzises Vokabular dafür entwickelt — das Kahn-Framework. Dieser Artikel erläutert es und ordnet jeden Teil FHIR zu: was der Validator bereits abdeckt und was einen vollständigen Datensatz erfordert.",
  "date": "2026-07-21",
  "author": "Nikolai Ryzhikov",
  "reading-time": "8 min read",
  "tags": [
    "SQL on FHIR",
    "Data Quality",
    "Analytics"
  ],
  "tldr": "Wenn Sie FHIR-Experten fragen, was Datenqualität bedeutet, erhalten Sie den Validator: Profile, Kardinalitäten, Bindings, Invarianten. Wenn Sie Data Engineers fragen, erhalten Sie dbt-Tests: not-null, unique, accepted values, freshness. Beide haben halb recht — und die Hälften überschneiden sich nicht so, wie beide Seiten annehmen. Die Grenze verläuft nicht zwischen Konformität und dem Rest — der FHIR-Validator prüft auch Plausibilität, via minValue/maxValue und Invarianten. Die Grenze ist der Geltungsbereich: Ein Validator beantwortet jede Frage, die in eine einzelne Ressource passt, und keine, die es nicht tut. Anteile, Toleranzen, ressourcenübergreifende Eindeutigkeit, referenzielle Integrität, Verteilungen, Aktualität — all das erfordert einen Datensatz. Und Vorsicht vor dem Wort „Validierung", das in diesen beiden Welten zwei völlig unterschiedliche Dinge bedeutet.",
  "utm-campaign": "analytics",
  "utm-content": "kahn-framework"
}
---

> For the complete documentation index, see [llms.txt](https://www.health-samurai.io/llms.txt).
> Use it to discover all available pages before guessing URLs.

---

## Was macht Daten gut — oder schlecht?

Das klingt wie eine einfache Frage, ist es aber nicht. Fragen Sie einen FHIR-Implementierer, was Datenqualität bedeutet, erhalten Sie den Validator: Profile, Kardinalitäten, Terminologiebindungen, Invarianten. Stellen Sie einem Data Engineer dieselbe Frage, erhalten Sie dbt-Tests: not-null, unique, accepted values, freshness.

Beide Antworten sind halb richtig, und die Hälften überschneiden sich nicht so, wie beide Seiten annehmen. Diese Verwirrung hat ihren Preis: Teams bauen entweder den Validator in SQL nach, oder sie lesen einen grünen Validierungslauf als „die Daten sind in Ordnung" — und beide Fehler zeigen sich spät, meist wenn eine Qualitätskennzahl eine Zahl liefert, die niemand verteidigen kann.

Die gute Nachricht ist, dass die Welt der Gesundheitsdaten bereits vor einem Jahrzehnt eine präzise Antwort auf die Frage „Was sind gute Daten?" erarbeitet hat — das **Kahn-Framework**. Dieser Artikel führt durch dieses Framework und ordnet es FHIR zu: was Ihr Validator bereits abdeckt und was er strukturell nicht leisten kann.

Ich bin bei der [Portierung der OMOP-Datenqualitätsprüfungen auf SQL on FHIR](/blog/fhir-data-quality-sql-on-fhir) darauf gestoßen. Die Mechanik war einfach; zu sagen, *welche* Prüfungen zum Validator gehören und welche nicht, war der schwierige Teil — und dieses Framework ist es, das die Grenze zieht.

## Kahn, in drei Fragen

Kahn et al., [*A Harmonized Data Quality Assessment Terminology and Framework*](https://pmc.ncbi.nlm.nih.gov/articles/PMC5051581/) (2016). Es handelt sich weder um ein Metrik-Set noch um ein Werkzeug — es ist eine **Terminologie**, geschrieben um ein Dutzend inkompatibler Vokabulare zusammenzuführen, die verschiedene Gruppen jeweils unabhängig voneinander entwickelt hatten. Genau deshalb hat sie sich durchgesetzt. Über Namen zu streiten ist günstiger als über Messungen zu streiten.

Es stellt drei Fragen an die Daten:

| Frage | Kahn nennt es | Beispiel |
|---|---|---|
| Ist es korrekt erfasst? | **Conformance** | `Sex` hat nur die Werte M, F oder U |
| Ist der Wert überhaupt vorhanden? | **Completeness** | 40 % der Observations enthalten keinen Wert |
| Kann der Wert geglaubt werden? | **Plausibility** | Ein Körpergewicht von 1000 kg |

Zwei Details sind wesentlich. Completeness ist *„ohne Bezug auf Datenwerte"* — sie zählt, wie oft etwas vorhanden ist, nie was es besagt. Und Plausibility bezieht sich auf **Glaubwürdigkeit, nicht auf Wahrheit**: ob 78 kg plausibel sind, nicht ob der Patient tatsächlich 78 kg wiegt. Nichts in den Daten kann die zweite Frage beantworten, und das Framework tut nicht so, als ob.

## Die Falle: „Validierung" bedeutet zwei verschiedene Dinge

Bevor wir weitermachen — dieses Wort wird einem FHIR-Publikum Probleme bereiten, daher möchte ich es vorab klären.

In FHIR bedeutet *Validierung* das Prüfen einer Ressource gegen eine StructureDefinition. Bei Kahn bedeutet *validation* den Vergleich von Daten mit einem **externen** Referenzwert, im Gegensatz zu *verification* anhand eigener Erwartungen. Unverwandte Konzepte, dasselbe Wort, und sie überschneiden sich gerade genug, um in die Irre zu führen:

- Eine Ressource gegen **US Core** zu validieren ist Kahn-*validation* — die Regel kam von außen.
- Dieselbe Ressource gegen **ein selbst erstelltes Profil** zu validieren ist Kahn-*verification* — die Regel stammt von Ihnen selbst.

Der Validator leistet in beiden Fällen identische Arbeit. Nur die Herkunft des Maßstabs hat sich geändert. Ein praktischer Test: **Können Sie diese Prüfung mit nichts als Ihrer eigenen Datenbank durchführen?** Ein Gewicht von 1000 kg — ja. Diabetesprävalenz, die der nationalen Rate entspricht — nein.

Eine Warnung, weil die falsche Version weit verbreitet ist: *verification = conformance, validation = completeness + plausibility* ist **nicht** das, was das Framework besagt. Die beiden Achsen kreuzen sich tatsächlich. Das Data Quality Dashboard von OHDSI, die Referenzimplementierung des Frameworks, befüllt alle sechs Zellen.

## Die eigentliche Grenze ist der Geltungsbereich, nicht die Kategorie

Hier liegt der Fehler, den die meisten Beschreibungen machen. Die Aufteilung lautet **nicht** „der Validator prüft Conformance, Qualitätsprüfungen erledigen den Rest." FHIR-Validierung reicht erheblich weiter als das.

Sie prüft Plausibility, solange die Frage in eine einzelne Ressource passt. `minValue[x]` / `maxValue[x]` ist buchstäblich eine Plausibilitätsbereichs-Einschränkung:

```json
{
  "path": "Observation.value[x]",
  "minValueQuantity": { "value": 0.5,  "unit": "kg" },
  "maxValueQuantity": { "value": 650,  "unit": "kg" }
}
```

Sie prüft zeitliche Plausibilität. Jede `Period` in FHIR trägt bereits `per-1`:

```
per-1: "If present, start SHALL have a lower or equal value than end"
       start.hasValue().not() or end.hasValue().not() or (start <= end)
```

Und sie prüft feldübergreifende Logik innerhalb einer Ressource, mittels Invarianten:

```
obs-7: "If Observation.code is the same as a Observation.component.code
        then the value element associated with the code SHALL NOT be present"
```

Der Validator ist also nicht auf die Struktur beschränkt. Was er nicht kann, ist alles, was eine **Population oder eine zweite Ressource** erfordert:

| Die Frage benötigt… | Beispiel | Validator |
|---|---|---|
| eine Ressource | Gewicht zwischen 0,5–650 kg; `end` nicht vor `start` | ✅ |
| einen Anteil | 40 % der Observations haben keinen Wert | ❌ kein Nenner |
| eine Toleranz | 5 % fehlend ist hier akzeptabel, dort 0 % erforderlich | ❌ Gültigkeit ist binär |
| eine andere Ressource | Observation datiert vor der Geburt des Patienten | ❌ Referenzen nicht aufgelöst |
| alle Datensätze | eine MRN pro Patient | ❌ kein Datensatz im Blick |
| eine Verteilung | mittleres Gewicht, Prävalenz, Drift | ❌ erfordert eine Population |
| einen externen Referenzwert | Prävalenz entspricht der nationalen Rate | ❌ kein Vergleichswert |

Daraus ergibt sich die treffende Kurzfassung:

> **Ein Validator beantwortet jede Frage, die in eine einzelne Ressource passt, und keine, die es nicht tut.**

### Der eine Fall, der genau auf der Grenze liegt

Ein Element ist `min=1` und fehlt. Der Validator meldet dies, und das sieht wie eine Completeness-Prüfung aus. Nach Kahn ist es **Conformance** — eine strukturelle Regel wurde verletzt, keine Häufigkeitserwartung.

Echte Completeness betrifft *optionale* Elemente, die so selten befüllt werden, dass die Spalte nutzlos ist. Dasselbe SQL in beiden Fällen; unterschiedliche Kategorie, unterschiedlicher Mechanismus, allein davon abhängig, ob das Element erforderlich war.

## Was nur ein Datensatz beantworten kann

Alles, was eine Eigenschaft des Datensatzes ist und nicht eines einzelnen Datensatzes darin. In SQL on FHIR sind das gewöhnliche Abfragen über eine abgeflachte View — der eigentliche Zweck dabei ist, dass sie die betroffenen Zeilen zurückgeben:

```sql
-- ressourcenübergreifende Eindeutigkeit: eine MRN pro Patient
SELECT mrn FROM patient_flat
GROUP BY mrn HAVING count(DISTINCT id) > 1
```

```sql
-- referenzielle Integrität: subject verweist auf einen Patient, der nicht vorhanden ist
-- (ein Bulk FHIR-Export schlägt hier öfter fehl, als man denkt)
SELECT o.id, o.patient_id
FROM obs o LEFT JOIN pat ON o.patient_id = pat.id
WHERE o.patient_id IS NOT NULL AND pat.id IS NULL
```

```sql
-- ressourcenübergreifende Zeitlogik: beobachtet vor der Geburt des Patienten
SELECT o.id FROM obs o JOIN pat ON o.patient_id = pat.id
WHERE o.effective < pat.birth_date
```

Dazu kommen jene ohne Entsprechung auf Einzeldatensatzebene: **Anteile** (40 % der Werte fehlen), **Toleranzen** (5 % akzeptabel hier, 0 % dort), **Verteilungen** (Mittelwert, Quantile, Ausreißer, Drift), **Aktualität** (der neueste Datensatz ist sechs Wochen alt — an keinem einzelnen Datensatz ist etwas falsch, der Datensatz ist veraltet), und die **Zusammenfassung**, die zum Dashboard wird.

Nichts davon ist eine Lücke, die ein besserer Validator schließen könnte. Es ist eine andere Frage.

Und die Kehrseite verdient Erwähnung, denn eine saubere Trennung braucht beide Hälften: **SQL-Prüfungen sehen nur, was eine Projektion offengelegt hat.** Der Validator inspiziert die gesamte Ressource — nicht projizierte Elemente, Slicing, Extensions, Invarianten über verschachtelte Strukturen, ValueSet-Expansion mit Hierarchie. Prüfungen tun das weder noch sollten sie es. Eine Prüfung, die eine Profilbeschränkung reimplementiert, ist eine zweite Quelle der Wahrheit, und sie wird von der ersten abweichen.

## Wo Kahn an seine Grenzen stößt

Zwei Lücken, auf die man sofort stößt, wenn man darauf aufbaut.

**Keine Aktualität.** „Kommen Daten noch an?" ist weder Conformance, Completeness noch Plausibility. Es ist ein reales und häufiges Versagen — die Anomalieerkennung von Databricks lässt sich auf Freshness und Completeness reduzieren — aber das Framework entstand vor dieser Betrachtungsweise. Entweder fügt man eine vierte Kategorie hinzu oder ordnet Freshness unter zeitlicher Plausibility ein und nimmt die Unschärfe in Kauf.

**Keine Genauigkeit.** Plausibility ist Glaubwürdigkeit, nicht Wahrheit. Ob ein erfasstes Gewicht dem tatsächlichen Gewicht des Patienten entspricht, lässt sich aus den Daten nicht beantworten.

Zwei Dinge, die OHDSI in der Praxis hinzufügen musste, verdienen es, neben der Taxonomie übernommen zu werden: ein **Level** (Datensatz / Spalte / Code) und ein **Schweregrad** (fatal / convention / characterization). Die Schweregradeinteilung über 27 Prüfungstypen ist aufschlussreich — 12 characterization, 8 convention, 7 fatal. **Die meisten Prüfungen beschreiben, statt zu urteilen** — eine nützliche Erwartungshaltung, bevor jemand ein Dashboard baut, das alles rot einfärbt.

## Was das bedeutet

> Ein Validator beantwortet *„ist diese Ressource wohlgeformt?"*
> Eine Prüfung beantwortet *„ist dieser Datensatz verwendbar?"*

Die zweite Frage ist ohne die erste bedeutungslos, und die erste ist ohne die zweite unzureichend. FHIR hat eine ausgezeichnete Antwort auf die erste Frage und bislang keinen Standardmechanismus für die zweite.

Das Ermutigende ist, wie wenig neu erfunden werden muss. Das Vokabular ist festgelegt. Die Referenzimplementierung läuft seit einem Jahrzehnt in der OMOP-Welt. Und in FHIR existieren die Bausteine bereits: eine ViewDefinition ist der Datensatz, eine SQLQuery ist die Prüfung, und `relatedArtifact` deklariert bereits den Abhängigkeitsgraphen. Was fehlt, ist nur die Semantik — auszudrücken, *dass diese Abfrage eine Prüfung ist, was sie misst und wie viel Abweichung akzeptabel ist*. Darum geht es bei der [SQL on FHIR-Datenqualitätsarbeit](https://github.com/HL7/sql-on-fhir/issues/375), und sie ist offen.

---

**Quellen**

- Kahn MG et al., *A Harmonized Data Quality Assessment Terminology and Framework for the Secondary Use of Electronic Health Record Data*, eGEMs 4(1):1244, 2016 — [PMC5051581](https://pmc.ncbi.nlm.nih.gov/articles/PMC5051581/). Alle Zitate stammen aus diesem Artikel.
- [OHDSI Data Quality Dashboard](https://github.com/OHDSI/DataQualityDashboard) — die 27-Typen-Klassifikationsmatrix befindet sich in `inst/csv/OMOP_CDMv5.4_Check_Descriptions.csv`.