{"id":1268,"date":"2024-02-23T17:33:31","date_gmt":"2024-02-23T16:33:31","guid":{"rendered":"https:\/\/sql.marcus-belz.de\/?p=1268"},"modified":"2024-03-01T13:59:26","modified_gmt":"2024-03-01T12:59:26","slug":"design-pattern-architektur-eines-etl-prozesses","status":"publish","type":"post","link":"https:\/\/sql.marcus-belz.de\/?p=1268","title":{"rendered":"Design Pattern \/\/ Architektur eines ETL-Prozesses"},"content":{"rendered":"\n<p>Dieser Artikel geh\u00f6rt zu der Artikelserie <a href=\"https:\/\/sql.marcus-belz.de\/wp-admin\/post.php?post=1246&amp;action=edit\">Datenqualit\u00e4t in einem ETL-Prozess<\/a>, in der ein Design Pattern vorgestellt wird, das extrahierte Daten pr\u00fcft, behandelt und schlechte Daten von der weiteren Verarbeitung ausschlie\u00dft. Ein wesentlicher Baustein des Design-Patterns ist die Aufteilung des ETL-Prozesses in kleine in sich geschlossene Arbeitspakete. Dieser Artikel stellt die Architektur eines ETL-Prozesses vor, die eine sichere Behandlung schlechter Daten erm\u00f6glicht und den Entwickler maximal bei der Entwicklung unterst\u00fctzt.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h1 class=\"wp-block-heading\">Inhalt<\/h1>\n\n\n\n<p><a href=\"#TheAcronymETL\">Aufgaben des ETL-Prozesses<\/a><br>\u00a0\u00a0\u00a0<a href=\"#Extract\">Extraktion<\/a><br>\u00a0\u00a0\u00a0<a href=\"#Tranform\">Transformation<\/a><br>\u00a0\u00a0\u00a0<a href=\"#TaskLoad\">Laden<\/a><br><a href=\"#TasksOfTheETLProcess\">Architektur des ETL-Prozesses<\/a><br>\u00a0\u00a0\u00a0<a href=\"#TasksOfTheETLProcess\">Arbeitspakete des ETL-Prozesses<\/a><br>\u00a0\u00a0\u00a0<a href=\"#ArchitectureExtract\">Extraktion<\/a><br>\u00a0\u00a0\u00a0<a href=\"#ArchitectureTransform\">Technische Transformation<\/a><br>\u00a0\u00a0\u00a0<a href=\"#ArchitectureHistorization\">Historisierung der technisch transformierten Daten<\/a><br>\u00a0\u00a0\u00a0<a href=\"#ArchitectureStructuralTransformation\">Strukturelle Transformation<\/a><br>\u00a0\u00a0\u00a0<a href=\"#ArchitectureHistorizationOfStructuralTranformedData\" data-type=\"post\" data-id=\"1268\">Historisierung der strukturell transformatierten Daten<\/a><br>\u00a0\u00a0\u00a0<a href=\"#ArchitectureLoad\">Laden<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"TheAcronymETL\">Aufgaben des ETL-Prozesses<\/h1>\n\n\n\n<p>Ein Prozess besteht aus den drei allgemeinen Schritte <strong>E<\/strong> = <em>Extract<\/em>, <strong>T<\/strong> = <em>Transform <\/em>und <strong>L<\/strong> = <em>Load<\/em>. Was aber genau in diesen \u00fcbergeordneten Arbeitsschritten durchzuf\u00fchren ist, bleibt Definitionssache.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"TaskExtract\">Extraktion<\/h2>\n\n\n\n<p>In diesem Schritt werden Daten aus verschiedenen Datenquellen extrahiert. Das k\u00f6nnen Datenbanken sein, Dateien oder auch APIs. Die zu extrahierenden Daten k\u00f6nnen strukturiert oder unstrukturiert sein und in verschiedenen Formaten vorliegen. In dieser Artikelserie werden ausschlie\u00dflich strukturierte Daten behandelt. Strukturierte Daten\u00adquellen sind relationale Datenbanksysteme, aber auch CSV-Dokumente sowie XML- und JSON-Dokumente, sofern ihre Daten\u00adelemente einer logischen Struktur folgen. Unstrukturierte Daten wie zum Beispiel Texte aus sozialen Netzwerken werden hier nicht ber\u00fccksichtigt.<\/p>\n\n\n\n<p>Bei dieser allgemeinen Definition der Extraktion bleibt jedoch unklar, was genau mit Extraktion gemeint ist. Eine konkrete Ausgestaltung des Extraktionsprozesses wird in den folgenden Abschnitten beschrieben:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Materialisierung der extrahierten Daten<\/li>\n\n\n\n<li>Erweiterte Aufgaben der Extraktion<\/li>\n\n\n\n<li>Keine Typisierung der Daten<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Materialisierung der extrahierten Daten<\/h3>\n\n\n\n<p>Das hier vorgestellte Design Pattern speichert alle extrahierten Daten in einer Datenbank. Die Daten sind so zu speichern, dass bei diesem Schritt kein technischer Grund vorliegen darf, dass die Daten nicht in der Datenbank gespeichert werden k\u00f6nnen. Einziger zul\u00e4ssiger Grund f\u00fcr einen Abbruch bei der Extraktion sind Probleme mit der Infrastruktur (Speicherplatz, Netzwerk, etc.). Die Speicherung von Daten in einer Datenbank bezeichne ich hier als <em>Materialisierung<\/em> der Daten. <\/p>\n\n\n\n<p>Die Extraktion und Materialisierung der extrahierten Daten haben vor allem drei Vorteile:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Minimierung der Zugriffsdauer auf die Daten des Quell\u00adsystems<\/li>\n\n\n\n<li>Verf\u00fcgbarkeit aller extrahierten Daten in einer Datenbank<\/li>\n\n\n\n<li>M\u00f6glichkeit der nachtr\u00e4glichen Fehleranalyse<\/li>\n<\/ul>\n\n\n\n<p>Der Zugriff auf Datenbanken des Quellsystems kann das Quellsystem so weit belasten, dass die Performance und Reaktionszeiten des Quellsystems in Mitleidenschaft gezogen werden. Durch eine Extraktion wird die Dauer des Zugriffs minimiert.<\/p>\n\n\n\n<p>Liegen alle extrahierten Daten in einer Datenbank vor, k\u00f6nnen die extrahierten Daten \u00fcber SQL weiterver\u00adarbeitet werden. F\u00fcr die Weiterverarbeitung ist insbesondere kein ETL-Tool erforder\u00adlich, das Daten aus unter\u00adschiedlichen Systemen integriert. Hierdurch werden unter anderem technische H\u00fcrden reduziert und im Zweifel sind nachfolgende Prozesse hinsichtlich Ausf\u00fchrung und Entwicklung wesentlich performanter.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Erweiterte Aufgaben der Extraktion<\/h3>\n\n\n\n<p>Bei Textdateien im Format <strong>XML <\/strong>und <strong>JSON <\/strong>(und ggf. auch CSV) verh\u00e4lt es sich bei der Materialisierung ein wenig anders. <strong>XML<\/strong>&#8211; und <strong>JSON<\/strong>-Dokumente werden vor der Extraktion der darin enthaltenen Daten in der Datenbank gespeichert. Als erweiterte Aufgabe der Extraktion sind die Attribute aus den Dokumenten \u00fcber m\u00e4chtige T-SQL-Funktionen wie zum Beispiel <strong>OPENXML<\/strong>&nbsp;oder <strong>OPENJSON<\/strong> zu extrahieren und in der Datenbank zu speichern. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Keine Typisierung der Daten<\/h3>\n\n\n\n<p>Insbesondere bei Datenlieferungen \u00fcber Text-Dateien sind problematisch. Die enthaltenen Daten liegen keineswegs typsicher vor. Ein Datum, das als Text geliefert wird, kann gegebenen falls nicht in einen Wert vom Typ date konvertiert werden. Zwischen dem die Daten liefernden Prozess und dem ETL-Prozess muss es eine Vereinbarung dar\u00fcber geben, in welchem Format zum Beispiel ein Datum geliefert wird (yyyy\/dd\/MM, dd.MM.yyyy, etc.). Die Konvertierung von Werten im Zuge der Extraktion ist eine Fehlerquelle und birgt die Gefahr des Abbruchs des ETL-Prozesses. Die Konvertierung von Daten in die Zieldatentypen ist im Rahmen der Extraktion daher nicht zul\u00e4ssig.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"TaskTranformation\">Transformation<\/h2>\n\n\n\n<p>Eine g\u00e4ngige Definition des Schrittes der Transformation k\u00f6nnte so lauten: Die Transformation hat zum Ziel, die extrahierten Daten in das gew\u00fcnschte Format zu bringen. Eine andere m\u00f6gliche Definition subsummiert die erforderlichen Aufgaben auch gerne unter dem Begriff der <em>Daten\u00adintegration<\/em>. Beide Definitionen und der Begriff <em>Datenintegration<\/em> sind alles und nichts sagend und geben keinen Hinweis auf die erforderlichen bzw. konkreten Ma\u00dfnahmen.<\/p>\n\n\n\n<p>Ausgehend von den extrahierten Daten fallen \u2013 gem\u00e4\u00df des hier vorgestellten Design Patterns  \u2013 grunds\u00e4tzlich zwei weitere Aufgaben an:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#DatatypeConversion\">Typisierung der extrahierten Daten<\/a><\/li>\n\n\n\n<li><a href=\"#CheckingDataquality\">Pr\u00fcfung der Datenqualit\u00e4t<\/a><\/li>\n\n\n\n<li>Optional: Historisierung<\/li>\n<\/ul>\n\n\n\n<p>Werden die Daten in Textdateien geliefert, dann sind die extrahierten Attribute zun\u00e4chst in die Zieldatentypen zu konvertieren. Dieses gilt \u00fcbrigens auch oft f\u00fcr den Fall, wenn Daten aus Datenbanken extrahiert werden und die Datentypen des Quell- und des Zielsystems auseinanderlaufen. Beschr\u00e4nken wir uns hier aber auf Textdateien als Datenquelle. Wie oben beschrieben, werden aus Textdateien extrahierte Werte zun\u00e4chst als Werte vom Typ <em>Text<\/em> gespeichert. Das Zielsystem erwartet aber stark typisierte Daten. So wird zum Beispiel ein Datum regelm\u00e4\u00dfig in einen Wert vom Typ <strong>date <\/strong>zu konvertieren sein.<\/p>\n\n\n\n<p>Die Pr\u00fcfung der Datenqualit\u00e4t ist zudem eine \u00e4u\u00dferst wichtige Aufgabe, die einen fundamentalen Einfluss auf das Ergebnis eines ETL-Prozesses hat. Sie beginnt hier mit der Pr\u00fcfung, ob ein gelieferter Wert in den Datentyp des entsprechenden Zielfeldes in dem Zielsystem konvertiert werden kann. Gegebenenfalls m\u00fcssen die gelieferten Daten auf Duplikate gepr\u00fcft werden. Es gibt noch zahlreiche andere sinnvolle und notwendige Pr\u00fcfungen sowie Aufgaben, die im Rahmen der Pr\u00fcfung der Datenqualit\u00e4t durchzuf\u00fchren sind.<\/p>\n\n\n\n<p>Im Zuge der Historisierung werden die als ge\u00e4ndert identifizierten Quelldaten (neue, ge\u00e4nderte oder gel\u00f6schte Daten) in separaten Tabellen fortgeschrieben, so dass immer nachvollziehbar ist, wann ein Datensatz eingef\u00fcgt, ge\u00e4ndert oder gel\u00f6scht wurde. Dieser Schritt ist optional. Ein Kollege hat die historisierten Daten mal <em>Gehirn des ETL-Prozesses<\/em> bezeichnet. Die Daten des nachfolgenden Zielsystems k\u00f6nnen so jeder Zeit aus den historisierten Daten wieder hergestellt werden. Nat\u00fcrlich erfordert die Historisierung weitergehende Wartungsaufgaben, wie zum Beispiel Sicherungsaufgaben.<\/p>\n\n\n\n<p>Der Begriff <em>Daten\u00adintegration<\/em> bezeichnet am ehesten die <strong>strukturelle Transformation<\/strong>. Es werden Daten aus verschiedenen Datenquellen gefiltert, zusammengef\u00fchrt und aggregiert. Obwohl es sich auch hier um eine Transformationsaufgabe handelt, wird diese Aufgabe &#8211; gem\u00e4\u00df des hier vorgestellten Design Patterns nicht im Rahmen des <strong>T<\/strong> des ETL-Prozesses durchgef\u00fchrt, sondern im Rahmen des <strong>L<\/strong> des ETL-Prozesses. An dieser Stelle angelangt ist es hilfreich, die in diesem Abschnitt beschrie\u00adbenen Transformationsaufgaben von der strukturellen Transformation begrifflich scharf zu trennen. Die Transformationsauf\u00adgaben, die in diesem Abschnitt beschrieben und im Rahmen des <strong>T<\/strong> des ETL-Prozesses durchzu\u00adf\u00fchren sind, werden daher als <strong>technische Transformation<\/strong> bezeichnet. Die Transformationsaufgaben, die in dem <strong>L<\/strong> des ETL-Prozesses durchzuf\u00fchren sind, werden als <strong>strukturelle Transformation <\/strong>bezeichnet.<\/p>\n\n\n\n<p>Die Grenzen f\u00fcr die Zuordnung einer Aufgabe zu einem der \u00fcber\u00adgeordneten Schritte eines ETL-Prozesses flie\u00dfend und am Ende eine Frage der Definition.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"DatatypeConversion\">Typisierung der extrahierten Daten<\/h3>\n\n\n\n<p>Sofern die Datenquelle eine Datenbank wie zum Beispiel <em>SQL&nbsp;Server<\/em> oder <em>Oracle<\/em> ist, sollten Daten \u00fcblicherweise streng typisiert vorliegen. Trotzdem die Daten einer Quelldatenbank in der Regel stark typisiert sind, kann auch hier eine Typisierung entsprechend des Datentyps in dem Zielsystem erforderlich sein.<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<p class=\"has-background\" style=\"background-color:#eeeeee\"><strong>Beispiel<br><\/strong>Als Beispiel kann die L\u00e4nge von Textfeldern genannt oder die Speicherung eines Datums ohne Angabe der Zeitzone genannt werden. Softwareentwickler legen bisweilen keinen starken Fokus auf die Begrenzung der Eingabe von Texten. Damit kann es vorkommen, dass zum Beispiel in einem Adressfeld in dem Quellsystem ganze Romane gespeichert werden k\u00f6nnen. Anwender, die solch eine L\u00fccke bei der Nutzung einer Anwendung entdecken, werden diese \u2013 erfahrungsgem\u00e4\u00df \u2013 auch nutzen, um dort weitere Informationen einzugeben, die dort einfach nicht hingeh\u00f6ren. Unterst\u00fctzt das Quellsystem keine Speicherung eines Datums mit Zeitzone, so ist die Zeitzone des Quellsystems zu ermitteln und bei der Konvertierung in den Zieldatentyp <em>Datum plus Zeitzone<\/em> zu ber\u00fccksichtigen.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<p>Bei der Verarbeitung von extrahierten Attributen, die aus einer Textdatei gelesen werden, ist immer eine Typisierung der extrahierten Werte in die Zieldatentypen erforderlich.<\/p>\n\n\n\n<p class=\"has-background\" style=\"background-color:#eeeeee\"><strong>Beispiel<br><\/strong>Im Zuge der Extraktion werden die extrahierten Attribute als Werte vom Typ <em>Text<\/em> gespeichert. Ein Text, den wir augenscheinlich als Datum interpretieren, muss nicht zwangsl\u00e4ufig in einen Wert vom Typ <em>Datum<\/em> konvertierbar sein. So ist der Text <strong>30-02-2023<\/strong> kein g\u00fcltiges Datum. Ein weiteres Beispiel: Der Text <strong>03-05-2023<\/strong> kann nicht ohne zus\u00e4tzliche Information \u00fcber die Datenquelle als Datum interpretiert werden. Die Interpretation nach amerikanischer Schreibweise gem\u00e4\u00df der Format\u00adzeichenfolge <strong>mm-dd-yyyy<\/strong> ergibt als Datum den <strong>05.03.2023<\/strong>, w\u00e4hrend die Interpretation gem\u00e4\u00df Deutscher Schreibweise und der hiesigen \u00fcblichen Formatzeichenfolge <strong>dd-mm-yyyy<\/strong> das Datum <strong>03.05.2023<\/strong> ergibt. F\u00fcr die korrekte Interpretation ist die Kenntnis \u00fcber das Datums-Format \u2013 also die Formatzeichenfolge \u2013 erforderlich. \u00c4hnliche Aufgaben und Herausforder\u00adungen gibt es bei Zahlen mit Bezug zu dem Dezimal- und Tausendertrennzeichen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"CheckingDataquality\">Pr\u00fcfung der Datenqualit\u00e4t<\/h3>\n\n\n\n<p>Bei der Pr\u00fcfung der Datenqualit\u00e4t werden die extrahierten und konvertierten Daten auf Voll\u00adst\u00e4ndigkeit und Korrektheit gepr\u00fcft. Diese Pr\u00fcfungen umfassen ein weites Feld. Beispiele hierf\u00fcr sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#CheckConversion\">Pr\u00fcfung der Typisierung<\/a><\/li>\n\n\n\n<li><a href=\"#CheckDuplicates\">Identifikation von Duplikaten<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/CheckSpelling\">Pr\u00fcfung der Schreibweise und Rechtschreibung von Texten<\/a><\/li>\n\n\n\n<li><a href=\"#CheckForeignKey\">Pr\u00fcfung von Fremdschl\u00fcsseln<\/a><\/li>\n\n\n\n<li><a href=\"#CheckMissingValues\">Pr\u00fcfung fehlender Werte f\u00fcr Pflichtfelder<\/a><\/li>\n\n\n\n<li><a href=\"#CheckBusinessLogic\">Validierung von Gesch\u00e4ftslogiken<\/a><\/li>\n<\/ul>\n<\/div><\/div>\n\n\n\n<p>In dem Artikel <a href=\"https:\/\/sql.marcus-belz.de\/?p=1246\" data-type=\"post\" data-id=\"1246\">Datenqualit\u00e4t in einem ETL-Prozess<\/a> wurde der Begriff der <strong>technischen Datenqualit\u00e4t<\/strong> vorgestellt. Die Pr\u00fcfung der technischen Datenqualit\u00e4t erfolgt auf den typisierten Daten. F\u00fcr die Pr\u00fcfung der Datenqualit\u00e4t in den typisierten Daten k\u00f6nnen einfach logische Bedingungen aufgestellt werden, \u00fcber die Fehler in einem Wert bzw. einem Datensatz identifiziert werden. Eine logische Bedingung wird technisch als <em>WHERE<\/em>-Klausel in dem ETL-Prozess hinterlegt und auf die typisierten Daten angewendet. Liefert eine <em>WHERE<\/em>-Klausel Datens\u00e4tze zur\u00fcck, enthalten diese in dem untersuchten Feld, auf das sich die <em>WHERE<\/em>-Klausel bezieht, einen Fehler.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CheckConversion\">Pr\u00fcfung der Typisierung<\/h4>\n\n\n\n<p>Der Erfolg oder Misserfolg der Typisierung hat unmittelbaren Einfluss auf alle nachfolgenden Aufgaben. Kann ein Eingangswert nicht in den Zieldaten\u00adtyp konvertiert werden, darf Datensatz, der den Fehler enth\u00e4lt, gegebenenfalls nicht weiterverarbeitet werden. \u00dcber das hier vorgestellte Design Pattern wird f\u00fcr alle gelieferten Quelldaten gepr\u00fcft, ob Eingangswerte in den jeweiligen Zieldatentyp konvertiert werden k\u00f6nnen.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CheckDuplicates\">Identifikation von Duplikaten<\/h4>\n\n\n\n<p>Die Identifikation von Duplikaten kann beliebig komplex sein. In dieser Artikelserie beschr\u00e4nke ich mich auf eine Kombination von Feldern, die in der Daten\u00adliefer\u00adung einer vorgegebenen Kardinalit\u00e4t entsprechen oder eindeutig sein muss (Kardinalit\u00e4t&nbsp;=&nbsp;1).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CheckSpelling\">Pr\u00fcfung der Schreibweise und Rechtschreibung von Texten<\/h4>\n\n\n\n<p>F\u00fcr Telefonnummern gibt es zahlreiche Schreibweisen. Nach der <em>DIN-Norm 5008<\/em> ist die Vorwahl ohne Klammern zu schreiben und von der restlichen Telefonnummer durch ein Leerzeichen zu trennen. Pr\u00fcfung auf korrekte Schreibweise eines Wertes kann im Rahmen der <em>technischen Transformation <\/em>durchgef\u00fchrt werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CheckForeignKey\">Pr\u00fcfung von Fremdschl\u00fcsseln<\/h4>\n\n\n\n<p>Enthalten die gelieferten und extrahierten Daten eine Fremd\u00adschl\u00fcssel\u00adbeziehung, ist die G\u00fcltigkeit eines gelieferten Fremdschl\u00fcssels im Zuge der technischen Transformation zu pr\u00fcfen.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CheckMissingValues\">Pr\u00fcfung fehlender Werte f\u00fcr Pflichtfelder<\/h4>\n\n\n\n<p>Ist ein Attribut in dem Zielsystem ein Pflichtfeld, f\u00fcr das ein Wert vorliegen muss, so sind die typisierten Daten daraufhin zu pr\u00fcfen, ob hier ein entsprechender Wert geliefert wird.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CheckBusinessLogic\">Validierung von Gesch\u00e4ftslogiken<\/h4>\n\n\n\n<p>Die Pr\u00fcfung von Gesch\u00e4ftslogiken ist ein weites Feld und kann beliebig komplex sein. Aber bereits durch die Pr\u00fcfung einfacher Gesch\u00e4ftslogiken, kann die Datenqualit\u00e4t im Zweifel erheblich verbessert werden. Als Beispiel f\u00fcr eine einfache Gesch\u00e4ftslogik k\u00f6nnte zum Beispiel das Geburtsdatum eines Kunden sein. Das Geburtsdatum darf selbstredend nicht in der Zukunft liegen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"TaskLoad\">Laden<\/h2>\n\n\n\n<p>Typisierte Daten werden im letzten Schritt des ETL-Prozesses strukturell entsprechend den Datenstrukturen des Zielsystems transfor\u00admiert, gegebenenfalls noch mal auf Datenfehler hin untersucht, gefiltert und aggregiert, historisiert und schlie\u00dflich in das Zielsystem geladen. Es sind die folgenden Aufgaben durchzuf\u00fchren:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Strukturelle Transformation<\/li>\n\n\n\n<li>Pr\u00fcfung der Datenqualit\u00e4t<\/li>\n\n\n\n<li>Filterung<\/li>\n\n\n\n<li>Aggregation<\/li>\n\n\n\n<li>Optional: Historisierung<\/li>\n\n\n\n<li>Laden der Daten in das Zielsystem<\/li>\n<\/ul>\n\n\n\n<p>Die zuvor technisch transformierten Daten k\u00f6nnen in verschiedene Zielsysteme geladen werden. Das Zielsystem, kann ein CRM-System sein, aber nat\u00fcrlich auch ein Data\u00adwarehouse. Die Aufgabe der strukturellen Transformation ist spezifisch f\u00fcr ein bestimmtes Zielsystem. Daher erfolgt die strukturelle Transformation im Rahmen des <strong>L<\/strong> aus dem ETL-Prozess. Auch hier gilt wieder: Die Grenze zwischen den \u00fcber\u00adgeordneten Schritten eines ETL-Prozesses sind flie\u00dfend und es ist eine Frage Definition in welchem Schritt des ETL-Prozesses, welche Aufgaben durch\u00adgef\u00fchrt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Strukturelle Transformation<\/h3>\n\n\n\n<p>Die strukturelle Transformation erfolgt ausschlie\u00dflich auf der Basis der typisierten, qualit\u00e4tsgesicherten und gegebenenfalls historisierten Daten, die als fehlerfrei erkannt wurden. Technisch betrachtet entspricht die strukturelle Transformation einem SELECT-Statement, das die Daten aus den historisierten Tabellen \u00fcber JOINs verkn\u00fcpft und entsprechend den Strukturen der Daten in dem Zielsystem aufbereitet. Im Rahmen der strukturellen Transformation sind unter anderem Fremdschl\u00fcssel zu ermitteln sowie Lookup-Werte aufzul\u00f6sen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ermittlung von Fremdschl\u00fcsseln<\/li>\n\n\n\n<li>Aufl\u00f6sung von Lookup-Werten<\/li>\n<\/ul>\n\n\n\n<p>Das Ergebnis der strukturellen Transformation wird &#8211; wie schon bei der Extraktion und der technischen Transformation &#8211; in einer Datenbank materialisiert, um auch diese Daten f\u00fcr eine Analyse und Fehlersuche verf\u00fcgbar zu machen. Die Datenstrukturen der strukturell transformierten Daten entsprechen weitestgehend den Datenstrukturen der Daten in dem Zielsystem. Insbesondere werden im Zuge der strukturellen Transformation die Spaltennamen und Datentypen des Arbeitsergebnisses so gew\u00e4hlt, wie sie durch das Zielsystem vorgegeben sind.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ermittlung von Fremdschl\u00fcsseln<\/h4>\n\n\n\n<p>K\u00f6nnen Fremdschl\u00fcssel nicht auf der Basis der extrahierten Daten ermittelt werden, sind Fremdschl\u00fcssel gegen die Daten des Zielsystems zu ermitteln.<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<p class=\"has-background\" style=\"background-color:#eeeeee\"><strong>Beispiel<\/strong><br>So werden L\u00e4nder in dem Zielsystem regelm\u00e4\u00dfig in einer separaten Tabelle gespeichert. Das Land <em>United States<\/em> in dem Zielsystem wird hier sowohl durch die L\u00e4nderbezeichnung aber auch \u2013 normalerweise \u2013 einen tech\u00adnischen Schl\u00fcssel (z.B. eine GUID) identifiziert. Bei der strukturellen Transformation eines Kunden ist das Land des Kunden, das in der Quelle durch den Text <em>United States<\/em> angegeben ist, in den Prim\u00e4rschl\u00fcssel des Landes <em>United States<\/em> des Zielsystems zu \u00fcbersetzen und als Fremdschl\u00fcssel auf das Land <em>United States<\/em> mit dem Kunden zu speichern.<\/p>\n<\/div><\/div>\n\n\n\n<p>Die Ermittlung des Fremdschl\u00fcssels erfordert entweder einen direkten lesenden Zugriff auf die Tabelle <em>L\u00e4nder<\/em> des Zielsystems oder \u2013 wenn kein direkter Zugriff besteht \u2013 diese ist vor der strukturellen Transformation zu lesen und die Daten sind in einer Datenbank verf\u00fcgbar zu machen. An diesem Punkt angelangt, handelt es sich bei dem Lesen der Tabelle <em>L\u00e4nder<\/em> wiederum um eine Extraktions\u00adaufgabe.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Aufl\u00f6sung von Lookup-Werten<\/h4>\n\n\n\n<p>H\u00e4ufig verwenden Quell- und Zielsysteme unterschiedliche Werte f\u00fcr die Speicherung eines Wertes eines Auswahlfeldes. Ein Auswahlfeld ist zum Beispiel ein Listenfeld, \u00fcber das die Anrede eines Kunden ausgew\u00e4hlt werden kann.<\/p>\n\n\n\n<p>In einer Datenbank wird selten die in der Anwendung angezeigte und ausgew\u00e4hlte Anrede gespeichert. Gespeichert wird m\u00f6glicherweise der Wert <em>1<\/em> f\u00fcr die Anrede <em>Herr<\/em> und der Wert <em>2<\/em> f\u00fcr die Anrede <em>Frau<\/em>. Die Kodierung der Anrede in dem Quellsystem und dem Zielsystem weicht normalerweise voneinander ab.<\/p>\n\n\n\n<p>Die Kodierung solcher Attribute ist h\u00e4ufig nicht in separaten Tabellen gespeichert. Die \u00dcbersetzung des Codes des Quellsystems in den Code des Zielsystems erfordert somit das Wissen um die Regeln f\u00fcr die \u00dcbersetzung des Codes. Die \u00dcbersetzung des Codes des Quellsystems in den Code des Zielsystem wird in Anlehnung an Begrifflichkeiten von <em>Microsoft CRM Dynamics<\/em> als <em>Aufl\u00f6sung von Lookup-Werten<\/em> bezeichnet. F\u00fcr die Aufl\u00f6sung von Lookup-Werten, sind die Codes des Quell- und des Zielsystems zu ermitteln und in einer Mapping-Tabelle zu speichern, die bei der strukturellen Transformation abgefragt wird.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pr\u00fcfung der Datenqualit\u00e4t<\/h3>\n\n\n\n<p>Die Erfahrung aus dem Projektgesch\u00e4ft hat gezeigt, dass die Ermittlung von Fremdschl\u00fcsseln sowie die Aufl\u00f6sung von Lookup-Werten eine gro\u00dfe Fehlerquelle darstellt, die in einer unvollst\u00e4ndigen oder fehlerhaften Ermittlung des Mappings der Codes des Quellsystem auf die Codes des Zielsystems begr\u00fcndet ist.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Filterung<\/h4>\n\n\n\n<p>Sofern es sich bei dem Zielsystem nicht um eine initiale Bef\u00fcllung mit Daten handelt, sind nur Daten mit bestimmten Eigenschaften in das Zielsystem zu laden. Die Filterung auf tats\u00e4chlich zu ladende Daten kann &#8211; sofern m\u00f6glich &#8211; bereits bei der technischen Transformation erfolgen. Ist dieses dort nicht m\u00f6glich, sind die Daten im Zuge der strukturellen Transformation zu filtern.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Datenaggregation<\/h4>\n\n\n\n<p>Gegebenenfalls sind Daten vor dem Laden des Zielsystems zu aggregieren.<\/p>\n\n\n\n<p>Wenn eine durchg\u00e4ngige Nachvollziehbarkeit aller Prozessschritte in einem ETL-Prozess gew\u00e4hrleistet sein soll, ist zu \u00fcberlegen, ob der Aggregations\u00adprozess auf den Daten der strukturellen Transformation nachgelagert als zus\u00e4tzlicher Prozessschritt vorzunehmen ist. Aggregierte Daten w\u00e4ren in diesem Fall in separaten Tabellen einer Datenbank zu speichern.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Historisierung<\/h4>\n\n\n\n<p>Wie schon bei der technischen Transformation k\u00f6nnen die strukturell transformierten und gepr\u00fcften Daten in separaten Tabellen fortzu\u00adschreiben. Neue Daten werden hier eingef\u00fcgt, ge\u00e4nderte Datens\u00e4tze werden hier aktualisiert und gel\u00f6schte Datens\u00e4tze als gel\u00f6scht markiert.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Laden der Daten in das Zielsystem<\/h4>\n\n\n\n<p>Das abschlie\u00dfende Laden der ge\u00e4nderten Daten in das Zielsystem erfolgt somit auf qualit\u00e4ts\u00adgesicherten strukturell transformierten und historisierten Daten. Es werden nur fehlerfreie Datens\u00e4tze, bei denen also Fremdschl\u00fcssel und Lookup-Wert erfolgreich ermittelt werden konnten, in das Zielsystem geladen.<\/p>\n\n\n\n<p>Technologisch beschr\u00e4nkt sich dieses Buch auf das Laden der \u00c4nderungs\u00addaten in eine Ziel-Datenbank. Die Aktualisierung in dieser Ziel-Datenbank erfolgt \u00fcber SQL-Statements, also \u00fcber INSERT-, UPDATE- und gegebenenfalls auch DELETE-Statements. Andere Zielsysteme \u2013 wie zum Beispiel Dynamics 365 von Microsoft \u2013 erfordern die Nutzung einer propriet\u00e4ren API, um Daten in das Zielsystem schreiben oder auch um Daten von dort lesen zu k\u00f6nnen. In diesem Fall ist es erforderlich, ein ETL-Tool wie zum Beispiel <em>SQL&nbsp;Server&nbsp;Integration Services,<\/em> zu nutzen.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ArchitectureETLProcess\">Architektur des ETL-Prozesses<\/h1>\n\n\n\n<p>Die hier vorgestellte Architektur eines ETL-Prozesses ist allgemeing\u00fcltig und kann unabh\u00e4ngig von der Art der zu extrahierenden Datenquellen und der Zielsysteme in Datenmigrations- und Datenintegrationsprojekten eingesetzt werden. Sie eignet sich ebenso f\u00fcr die Datenbewirtschaftung eines Datawarehouse. Der ETL-Prozess wird in kleine in sich geschlossene Arbeitspakete heruntergebrochen. Die durchzuf\u00fchrenden Aufgaben der Arbeitspakete sind trennscharf definiert. Im Zuge der Datenverarbeitung wird die Datenqualit\u00e4t gepr\u00fcft. Nach Abschluss der Arbeit in einem Arbeitspaket werden nur fehlerfreie Daten an das jeweils folgende Arbeitspaket weitergereicht. Am Ende des Prozesses stehen qualit\u00e4tsgesicherte Daten in Datenstrukturen zur Verf\u00fcgung, die \u00e4hnlich zu den Strukturen in dem Zielsystem sind und ohne weitere Transformationsaufgaben direkt dorthin geladen werden k\u00f6nnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"TasksOfTheETLProcess\">Arbeitspakete des ETL-Prozesses<\/h2>\n\n\n\n<p>Das folgende Schaubild veranschaulicht die Arbeitspakete des hier vorge\u00adstellten ETL-Prozesses:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"251\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1024x251.png\" alt=\"Steps of this ETL process\" class=\"wp-image-1369\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1024x251.png 1024w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-300x74.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-768x188.png 768w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image.png 1077w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In der Abbildung werden in der oberen Zeile zun\u00e4chst die \u00fcbergeordneten Schritte analog zu dem Akronym <strong>ETL<\/strong> dargestellt: <strong>Extract<\/strong>, <strong>Transform <\/strong>und <strong>Load<\/strong>. Die untere Zeile benennt die konkreten Arbeitspakete des ETL-Prozesses und ordnet diese einem \u00fcbergeordneten Schritt zu. Jedem Arbeitspaket ist ein Datenbankschema zugeordnet. In der Mitte werden die von dem ETL-Prozesse verwendeten Schemas je Arbeitspaket benannt (<strong>E0<\/strong>&#8211;<strong>L2<\/strong>). Im Zuge der Datenverarbeitung werden die Daten von Arbeitspaket zu Arbeitspaket bzw. Schema zu Schema weitergereicht. Der ETL-Prozess besteht aus den folgenden Arbeitspaketen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extraktion der Daten<\/li>\n\n\n\n<li>Technische Transformation<\/li>\n\n\n\n<li>Historisierung der technisch transformierten Daten<\/li>\n\n\n\n<li>Strukturelle Transformation<\/li>\n\n\n\n<li>Historisierung der strukturell transformierten Daten<\/li>\n\n\n\n<li>Laden der Daten in das Zielsystem<\/li>\n<\/ul>\n\n\n\n<p>Die Arbeitspakete <strong>Technische Transformation <\/strong>und <strong>Strukturelle Trans\u00adformation <\/strong>pr\u00fcfen die Datenqualit\u00e4t der transformierten Daten und reichen nur fehlerfreie Daten an das folgende Arbeitspaket weiter. Die Pr\u00fcfung der Daten ist in der Abbildung durch die dunklen Pfeil-Spitzen dargestellt. Die nachfolgenden Abschnitte fassen die Arbeitsschritte der einzelnen Arbeitspakete zusammen und geben einen \u00dcberblick \u00fcber die zu verwen\u00addende Technologie, mit der die Arbeitsschritte in den Arbeitspaketen durchge\u00adf\u00fchrt werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ArchitectureExtract\">Extraktion<\/h2>\n\n\n\n<p>Ziel der Extraktion ist, alle zu verarbeitenden Daten zun\u00e4chst in der Schnittstellendatenbank zu speichern. Bei der Extraktion ist zu unter\u00adscheiden, ob die zu extrahierenden Daten aus einer Datenbank oder Dokumenten mit tabellen\u00e4hnlichen Strukturen \u2013 wie zum Beispiel EXCEL- oder CSV-Dokumente \u2013 gelesen werden, oder ob Dokumente mit komplexen logischen Strukturen \u2013 wie zum Beispiel XML oder JSON \u2013 zu verarbeiten sind.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Extraktion aus einer Datenbank<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1023\" height=\"202\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1.png\" alt=\"Extraction from a database\" class=\"wp-image-1372\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1.png 1023w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1-300x59.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1-768x152.png 768w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/figure>\n\n\n\n<p>Werden Daten aus einer Datenbank oder tabellen\u00e4hnlichen Strukturen gelesen, werden die Attribute\/Spalten zun\u00e4chst in Tabellen des Schemas <strong>E1<\/strong> materialisiert. Die Strukturen der Tabellen in dem Schema <strong>E1<\/strong> entsprechen weitestgehend den Strukturen in dem Quellsystem. Sind Daten aus einer Datenbank zu extrahieren, werden die Daten mit den Datentypen gespeichert, in denen sie in dem Quellesystem abgelegt sind. Werden die Datentypen des Quellsystems nicht durch <em>SQL&nbsp;Server<\/em> unterst\u00fctzt, sind die Daten der Datenquelle in den Tabellen des Schemas <strong>E1<\/strong> mit dem Datentyp <strong>nvarchar<\/strong> zu speichern.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Extraktion aus Dokumenten mit tabellen\u00e4hnlichen Strukturen<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1023\" height=\"202\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-3.png\" alt=\"Extraction of EXCEL\/CSV documents\" class=\"wp-image-1376\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-3.png 1023w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-3-300x59.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-3-768x152.png 768w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/figure>\n\n\n\n<p>Daten aus Dokumenten mit tabellen\u00e4hnlichen Strukturen, wie zum Beispiel EXCEL- und CSV-Dokumente, k\u00f6nnen nicht typsicher geliefert werden. H\u00e4ufig werden diese Dokumente manuell erstellt und gepflegt und der ETL-Prozess kann sich nicht darauf verlassen, dass in einer Spalte zum Beispiel ein g\u00fcltiges Datum geliefert wird. Um sicherzustellen, dass alle Daten aus diesen Dokumenten in der <em>Schnittstellendatenbank <\/em>in den Tabellen des Schemas <strong>E1<\/strong> materialisiert werden k\u00f6nnen, sind alle Daten zun\u00e4chst mit dem Datentyp <strong>nvarchar<\/strong> zu speichern. F\u00fcr die Speicherung in diesen Tabellen sind maximale Textl\u00e4ngen zu verwenden, um sicher zu stellen, dass die Daten dort materialisiert werden k\u00f6nnen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Extraktion aus Dokumenten mit komplexen logischen Strukturen<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1023\" height=\"201\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-4.png\" alt=\"Extraction of XML\/JSON documents\" class=\"wp-image-1379\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-4.png 1023w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-4-300x59.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-4-768x151.png 768w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/figure>\n\n\n\n<p>Sind XML-\/JSON-Dokumente zu verarbeiten, werden diese zun\u00e4chst selbst in Tabellen des Schemas <strong>E0<\/strong> gespeichert. Die Extraktion der Attribute erfolgt in Tabellen des Schemas <strong>E1<\/strong>. Hierbei werden die Dokumente verarbeitet, die im ersten Arbeitsschritt in den Tabellen des Schemas <strong>E0<\/strong> gespeichert wurden.<\/p>\n\n\n\n<p>Attribute aus Text-Dateien werden in den Tabellen des Schemas <strong>E1<\/strong> als Werte vom Typ <strong>nvarchar<\/strong> gespeichert. F\u00fcr die Speicherung in diesen Tabellen sind maximale Textl\u00e4ngen zu verwenden, um sicher zu stellen, dass die Daten dort gespeichert werden k\u00f6nnen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Technologie<\/strong><\/h3>\n\n\n\n<p>Die Extraktion von Daten aus einer Datenbank oder tabellen\u00e4hnlichen Strukturen kann mit <em>SQL&nbsp;Server&nbsp;Integration&nbsp;Services<\/em> (SSIS) von Microsoft oder auch jedem anderen ETL-Tool durchgef\u00fchrt werden. Sind XML- oder JSON-Dokumente zu extrahieren, werden diese Dokumente ebenfalls mit <em>SSIS<\/em> zun\u00e4chst in die Tabellen des Schemas <strong>E0<\/strong> geladen. Die Extraktion der Attribute aus den Dokumenten erfolgt \u00fcber die m\u00e4chtigen T-SQL-Funktionen <strong>OPENXML<\/strong>&nbsp;oder <strong>OPENJSON<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Zusammenfassun<\/strong>g<\/h3>\n\n\n\n<p>Diese Vorgehensweise der Extraktion bietet zahlreiche Vorteile. Durch Verwendung eines ETL-Tools wie <em>SSIS<\/em>, das einen hohen Grad der Parallelisierung in der Datenverarbeitung unterst\u00fctzt, k\u00f6nnen die Daten hoch performant in den Tabellen der Schemas <strong>E0<\/strong> und <strong>E1<\/strong> materialisiert werden. Vorsysteme werden minimal belastet und die Daten stehen f\u00fcr eine weitere Verarbeitung, wie zum Beispiel die Extraktion der Attribute aus XML- und JSON-Dokumenten \u00fcber die T-SQL-Funktionen <strong>OPENXML<\/strong>&nbsp;oder <strong>OPENJSON<\/strong> in der Schnittstellendatenbank zur Verf\u00fcgung. Die materia\u00adlisierten Daten erm\u00f6glichen zudem im Fehlerfall eine Analyse der Ursachen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ArchitectureTransform\">Technische Transformation<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"393\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-5-1024x393.png\" alt=\"Technical transformation\" class=\"wp-image-1400\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-5-1024x393.png 1024w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-5-300x115.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-5-768x295.png 768w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-5.png 1068w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In dem \u00fcbergeordneten Schritte der Transformation erfolgt nach diesem Design-Pattern die oben beschriebene technische Transformation. Diese umfasst die folgenden Arbeitsschritte:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Typ-Konvertierung<\/li>\n\n\n\n<li>Pr\u00fcfung der technischen Datenqualit\u00e4t<\/li>\n\n\n\n<li>Protokollierung von Datenfehlern<\/li>\n\n\n\n<li>Markierung fehlerhafter Datens\u00e4tze<\/li>\n\n\n\n<li>Berechnung von Hashwerten<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Typ-Konvertierung<\/strong><\/h3>\n\n\n\n<p>Das Ergebnis der technischen Transformation sind typisierte Daten, wie sie im Zielsystem erwartet werden. Die Typisierung kann auf Basis von Metadaten \u00fcber generische benutzerdefinierte gespeicherte Prozeduren (<em>Stored Procedures<\/em>) erfolgen und materialisiert die Daten in der Datenbank in Tabellen des Schemas <strong>T1<\/strong>.<\/p>\n\n\n\n<p>Je Attribut aus den Tabellen des Schemas <strong>E1<\/strong> werden zwei Spalten in den Tabellen des Schemas <strong>T1<\/strong> bereitgestellt. Die erste Spalte nimmt die extrahierten Daten in dem Datentyp auf, in dem diese in den Tabellen des Schemas <strong>E1<\/strong> gespeichert sind. Die zweite Spalte speichert den typisierten Wert in dem Zieldatentyp, sofern die Daten in den Zieldatentyp konvertiert werden k\u00f6nnen. Kann ein Wert nicht konvertiert werden, so wird in der jeweils zweiten Spalte ein <em>NULL<\/em> gespeichert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Pr\u00fcfung der technischen Datenqualit\u00e4t<\/strong><\/h3>\n\n\n\n<p>Nach erfolgter Typisierung wird das Ergebnis durch Vergleich der Spaltenpaare auf Probleme bei der Typ-Konvertierung hin gepr\u00fcft. Da die Typ-Konvertierung aus\u00adschlie\u00dflich einen technischen Charakter hat, wird diese Pr\u00fcfung hier auch als <em>Pr\u00fcfung der technischen Datenqualit\u00e4t<\/em> bezeichnet. Die Fehlerpr\u00fcfung kann bereits hier auch um die Pr\u00fcfung einfacher Gesch\u00e4ftslogiken erweitert werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Protokollierung von Datenfehlern<\/strong><\/h3>\n\n\n\n<p>Gefundene Datenfehler werden in einer les- und auswertbaren Form in einer Fehlertabelle protokolliert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Markierung fehlerhafter Datens\u00e4tze<\/strong><\/h3>\n\n\n\n<p>Enth\u00e4lt ein Datensatz mindestens einen Fehler, wird dieser Datensatz als fehlerhaft markiert, damit diese von der weiteren Verarbeitung ausge\u00adschlossen werden kann. Die Markierung erfolgt in einer Spalte, in der die Anzahl der gefundenen Fehler gespeichert wird. Fehlerfreie Datens\u00e4tze weisen in dieser Spalte ein <em>NULL<\/em> auf.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Berechnung von Hashwerten<\/strong><\/h3>\n\n\n\n<p>Der letzte Arbeitsschritt der technischen Transformation ist die Berechnung und Speicherung von zwei Hashwerten je Datensatz. Der erste Hashwert repr\u00e4sentiert die Felder des fachlichen Schl\u00fcssels eines Datensatzes, der zweite Hashwert alle \u00fcbrigen Felder. \u00dcber diese beiden Felder k\u00f6nnen in dem nachfolgenden Arbeitspaket <strong>Historisierung technisch transformierter Daten <\/strong>\u00c4nderungsdatens\u00e4tze identi\u00adfiziert werden. Hashwerte werden nur f\u00fcr fehlerfreie Datens\u00e4tze berechnet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Technologie<\/strong><\/h3>\n\n\n\n<p>Die Konvertierung der extrahierten Werte in die Zieldatentypen, die Pr\u00fcfung auf Datenfehler, Markierung fehlerhafter Datens\u00e4tze und Berechnung von Hashwerten kann \u00fcber generische gespeicherte Prozeduren erledigt werden, die auf der Basis von Metadaten entsprechende dynamische SQL-Statements erstellen. Dieses erfordert einmal Aufwand f\u00fcr die Implementierung solcher Prozeduren. Die genannten Aufgaben k\u00f6nnen dann  durch einfache Prozedur-Aufrufe erledigt werden. Dieses reduziert langfristig den Entwicklungs-Aufwand und unterst\u00fctzt den Entwickler durch maximale Wiederverwendbarkeit. <\/p>\n\n\n\n<p><strong>Diese Artikelserie befindet sich derzeit im Aufbau. In einem folgenden Artikel werde ich gespeicherte generische Prozeduren vorstellen, die die genannten Aufgaben \u00fcbernehmen.     <\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ArchitectureHistorization\">Historisierung der technisch transformierten Daten<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"290\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-6-1024x290.png\" alt=\"Historization of technically transformed data\" class=\"wp-image-1498\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-6-1024x290.png 1024w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-6-300x85.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-6-768x218.png 768w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-6.png 1054w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Die Historisierung umfasst die folgenden Arbeitsschritte:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Historisierung<\/li>\n\n\n\n<li>Identifikation von \u00c4nderungsdaten<\/li>\n\n\n\n<li>Identifikation \u00fcber Hashwerte<\/li>\n\n\n\n<li>Speicherung von Hashwerten<\/li>\n\n\n\n<li>\u00dcbernahme ausschlie\u00dflich fehlerfreier Datens\u00e4tze<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Historisierung<\/h3>\n\n\n\n<p>Historisierung bedeutet, dass gelieferte Daten in einer Datenbank fortgeschrieben werden. Aus dem Bereich des Data-Warehousing sind unter dem Begriff <em><a href=\"https:\/\/de.wikipedia.org\/wiki\/Slowly_Changing_Dimensions\">Slowly Changing Dimensions <\/a><\/em>verschiedene Typen der Historisierung bekannt, die festlegen, wie genau Daten fortgeschrieben werden k\u00f6nnen. Der Begriff <em>Slowly Changing Dimensions<\/em> ist auch unter der Kurzform <em>SCD<\/em> bekannt. Unter diesem Begriff werden bis zu 6 Typen der Historisierung beschrieben, von denen hier nur zwei erw\u00e4hnt werden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SCD 1<\/strong><br>SCD 1 beschreibt dem Grunde nach keine echte Historisierung von Daten. Ein bereits zuvor geladener Datensatz wird mit einem ge\u00e4nderten Datensatz lediglich \u00fcberschrieben. Es werden also immer nur die jeweils letzten \u00c4nderungen eines Datensatzes gespeichert.<\/li>\n\n\n\n<li><strong>SCD 2<\/strong><br>Gem\u00e4\u00df SCD 2 erhalten alle Tabellen, in denen Daten historisiert werden, zwei zus\u00e4tzliche Spalten <strong>ValidForm<\/strong> und <strong>ValidTill<\/strong>, in denen der G\u00fcltigkeitszeitraum des Datensatzes angegeben ist. Aktuell g\u00fcltige Datens\u00e4tze sind unbegrenzt g\u00fcltig, was in <strong>ValidTill<\/strong> zum Beispiel durch ein <em>NULL <\/em>angezeigt wird. Werden zu einem aktuellen Datensatz \u00c4nderungsdaten geliefert, wird der zuletzt g\u00fcltige Datensatz in der Spalte <strong>ValidTill<\/strong> mit dem Datum, ab dem der \u00c4nderungsdatensatz g\u00fcltig ist, aktualisiert und der \u00c4nderungsdatensatz wiederum mit <strong>ValidTill<\/strong> = <em>NULL <\/em>eingef\u00fcgt.<\/li>\n<\/ul>\n\n\n\n<p>Eine Historisierung ist optional. Insbesondere bei einem Delta-Load kann sie jedoch hilfreich oder gar erforderlich sein. Nehmen wir an, ein Kunde hat eine neue Bestellung get\u00e4tigt. Bei einem Delta-Load wird die Bestellung geliefert, aber nicht der Kunde, da sich dieser nicht ge\u00e4ndert hat. Eine Aufl\u00f6sung der Fremdschl\u00fcsselbeziehung zwischen Bestellung und Kunde kann mit den gelieferten Daten nicht erfolgen. F\u00fcr eine Aufl\u00f6sung der Fremdschl\u00fcsselbeziehung zwischen Bestellung und Kunde sind entweder die Kundendaten aus dem Zielsystem zu extrahieren oder die Kunden sind in der Datenbank zu historisieren, damit bei folgenden Ausf\u00fchrungen des ETL-Prozesses der Kunde verf\u00fcgbar ist.<\/p>\n\n\n\n<p>Historisierung im Kontext des hier vorgestellten ETL-Prozesses bedeutet, dass nur fehlerfreie und ge\u00e4nderte Datens\u00e4tze historisiert werden. Die Historisierung kann nach <em>SCD 1<\/em> oder <em>SCD 2<\/em> erfolgen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Identifikation von \u00c4nderungsdaten <\/h3>\n\n\n\n<p>Die Historisierung erfordert, dass wir \u00c4nderungsdatens\u00e4tze in dem Quell\u00adsystem und in der Folge auch in den historisierten Tabellen erkennen k\u00f6nnen. H\u00e4ufig stellt das Quellsystem keine oder nur unzureichende Informationen dar\u00fcber bereit, wann ein Datensatz eingef\u00fcgt, ge\u00e4ndert oder gel\u00f6scht wurde. Wird zum Beispiel eine CSV-Datei aus einem manuell bearbeiteten EXCEL-Dokument erstellt, k\u00f6nnen wir immer davon ausgehen, dass keine (belastbaren) Informationen \u00fcber eine \u00c4nderung eines Datensatzes vorliegen. Vor diesem Hintergrund werden nach diesem Design Pattern \u00c4nderungsdaten immer \u00fcber die Daten selbst ermittelt. Hierf\u00fcr werden die im Zuge der <a href=\"#ArchitectureTransform\">Technische Transformation<\/a> berechneten Hashwerte verwendet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Identifikation \u00fcber Hashwerte<\/h3>\n\n\n\n<p>In dem Abschnitt  <a href=\"#ArchitectureTransform\">Technische Transformation<\/a> wurden f\u00fcr fehlerfreie Daten Hashwerte \u00fcber die Prim\u00e4rschl\u00fcsselfelder sowie die nicht Prim\u00e4rschl\u00fcsselfelder berechnet. Diese beiden Hashwerte k\u00f6nnen f\u00fcr die Identifikation von \u00c4nderungsdatens\u00e4tzen verwendet werden. Neue, ge\u00e4nderte und auch gel\u00f6schte Datens\u00e4tze k\u00f6nnen durch Vergleich der Hashwerte f\u00fcr den fachlichen Schl\u00fcssel und der Attribute in den Tabellen den Tabellen, die die extrahierten Daten (Schema <strong>T1<\/strong>) enthalten und den historisierten Daten (Schema <strong>T2<\/strong>) identifiziert werden:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td colspan=\"4\"><strong>Hashwert<\/strong>e<\/td><td rowspan=\"3\"><strong>Art der \u00c4nderung<\/strong><strong><\/strong><\/td><\/tr><tr><td colspan=\"2\"><strong>Fachlicher Schl\u00fcssel<\/strong><\/td><td colspan=\"2\"><strong>Attribute<\/strong><strong><\/strong><\/td><\/tr><tr><td><strong>extrahiert<\/strong> <strong>[T1]<\/strong><\/td><td><strong>historisiert<\/strong> <strong>[T2]<\/strong><\/td><td><strong>extrahiert<\/strong><\/td><td><strong>historisiert<\/strong><\/td><\/tr><tr><td colspan=\"2\">gleich<\/td><td colspan=\"2\">gleich<\/td><td>Keine \u00c4nderung vorhanden<\/td><\/tr><tr><td colspan=\"2\">gleich<\/td><td colspan=\"2\">ungleich<\/td><td>Datensatzes wurde ge\u00e4ndert<\/td><\/tr><tr><td colspan=\"2\">In <strong>T1<\/strong> und nicht in <strong>T2<\/strong> vorhanden<\/td><td colspan=\"2\">&nbsp;<\/td><td>Neuer Datensatz<\/td><\/tr><tr><td colspan=\"2\">In <strong>T2<\/strong> und nicht in <strong>T1<\/strong> vorhanden<\/td><td colspan=\"2\">&nbsp;<\/td><td>Datensatz wurde gel\u00f6scht<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Identification of new, modified or deleted rows<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Speicherung von Hashwerten<\/strong><\/h3>\n\n\n\n<p>Wird ein neuer Datensatz in den historischen Tabellen eingef\u00fcgt, aktualisiert oder dort als gel\u00f6scht markiert, sind dort auch die Hashwerte des neuen, ge\u00e4nderten oder gel\u00f6schten Datensatzes zu speichern beziehungsweise zu aktualisieren. Hierdurch wird sichergestellt, dass die dort gespeicherten Hashwerte den Status Quo in den Quellsystemen darstellen und zu jederzeit (in folgenden Ausf\u00fchrungen des ETL-Prozesses) eine Identifikation von \u00c4nderungsdatens\u00e4tzen \u00fcber die Hashwerte m\u00f6glich ist.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>\u00dcbernahme ausschlie\u00dflich fehlerfreier Datens\u00e4tze<\/strong><\/h3>\n\n\n\n<p>Die \u00dcbernahme eines fehlerhaften Datensatzes und das sp\u00e4tere Laden dieses Datensatzes in das Zielsystem k\u00f6nnte einen Fehler verursachen und ggf. den gesamten ETL-Prozess zum Abbruch bringen. Es werden daher nur fehlerfreie \u00c4nderungsdatens\u00e4tze aus den Tabellen des Schemas <strong>T1<\/strong> in den Tabellen des Schemas <strong>T2<\/strong> gespeichert. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ArchitectureStructuralTransformation\">Strukturelle Transformation<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"387\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-7-1024x387.png\" alt=\"Structural Transformation\" class=\"wp-image-1510\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-7-1024x387.png 1024w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-7-300x113.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-7-768x290.png 768w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-7.png 1082w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Die strukturelle Transformation umfasst die folgenden Arbeitsschritte:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Strukturelle Transformation und Aufl\u00f6sung von Fremdschl\u00fcsselbeziehungen und Lookup-Werten<\/li>\n\n\n\n<li>Pr\u00fcfung der strukturellen Datenqualit\u00e4t<\/li>\n\n\n\n<li>Protokollierung von Datenfehlern<\/li>\n\n\n\n<li>Markierung fehlerhafter Datens\u00e4tze<\/li>\n\n\n\n<li>Berechnung von Hashwerten<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Strukturelle Transformation und Aufl\u00f6sung von Fremdschl\u00fcsselbe\u00adziehungen und Lookup-Werten<\/strong><\/h3>\n\n\n\n<p>Als Ergebnis der strukturellen Transformation liegen die Daten in Tabellen\u00adstrukturen vor, wie sie im Zielsystem erwartet werden. Die strukturelle Transformation erfolgt \u00fcber SQL-Statements mit den erforderlichen JOINs in der FROM-Klausel. Die Entwicklung erfordert hinreichende Kenntnis \u00fcber die Daten, die Zusam\u00admenh\u00e4nge und vor allem Fremdschl\u00fcsselbeziehungen zwischen den Tabellen in einem Quellsystem beziehungsweise den zu integrierenden Quell\u00adsystemen.<\/p>\n\n\n\n<p>Neben der eigentlichen strukturellen Transfor\u00admation der Quelldaten l\u00f6st die strukturelle Transformation Fremdschl\u00fcssel\u00adbeziehungen f\u00fcr das Zielsystem auf und ermittelt zu Lookup-Werten den zu speichernden Code. Das Ergebnis der strukturellen Transformation wird in Tabellen des Schemas <strong>L1<\/strong> gespeichert, die bez\u00fcglich Tabellenstruktur, Spaltennamen und Datentypen \u00e4hnlich zu den Strukturen des Zielsystems sind.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Pr\u00fcfung der strukturellen Datenqualit\u00e4t<\/strong><\/h3>\n\n\n\n<p>Der letzte Arbeitsschritt der strukturellen Transformation ist die Berechnung von zwei Hashwerten je Datensatz. Der erste Hashwert repr\u00e4sentiert die Felder des fachlichen Schl\u00fcssels eines strukturell transformierten Daten\u00adsatzes, der zweite Hashwert alle \u00fcbrigen Attribut-Felder. \u00dcber diese beiden Hashwerte k\u00f6nnen in dem nachfolgenden Arbeitspaket <em>Historisierung<\/em> <em>strukturell transformierter Daten<\/em> \u00c4nderungsdatens\u00e4tze leicht identifiziert werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Protokollierung von Datenfehlern<\/strong><\/h3>\n\n\n\n<p>Gefundene Datenfehler werden in einer les- und auswertbaren Form in einer Fehlertabelle protokolliert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Markierung fehlerhafter Datens\u00e4tze<\/strong><\/h3>\n\n\n\n<p>Enth\u00e4lt ein Datensatz mindestens einen Fehler, wird dieser Datensatz als fehlerhaft markiert, damit diese von der weiteren Verarbeitung ausge\u00adschlossen werden kann. Die Markierung erfolgt in einer Spalte, in der die Anzahl der gefundenen Fehler gespeichert wird. Fehlerfreie Datens\u00e4tze weisen in dieser Spalte ein <em>NULL<\/em> auf.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ArchitectureHistorizationOfStructuralTranformedData\">Historisierung der strukturell transformierten Daten<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"288\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-8-1024x288.png\" alt=\"Structural Historization\" class=\"wp-image-1518\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-8-1024x288.png 1024w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-8-300x85.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-8-768x216.png 768w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-8.png 1072w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Die Historisierung der strukturell transformierten Daten umfasst die gleichen Arbeitsschritte wie bei der Historisierung der technisch transformierten Daten. Die Historisierung der strukturell transformierten Daten ist ein optionaler Schritt, da diese &#8211; wenn die Daten der technischen Transformation historisiert wurden &#8211; jederzeit im Zuge strukturellen Transformation der wieder hergestellt werden k\u00f6nnen. <\/p>\n\n\n\n<p>Die Historisierung der strukturell transformierten Daten aus den Tabellen des Schemas <strong>L1<\/strong> erfolgt in den Tabellen des Schemas <strong>L2<\/strong>. Die Vorgehensweise ist identisch zu der Historisierung der Daten aus dem Schema <strong>T1<\/strong> in den Tabellen des Schemas <strong>T2<\/strong>. Es werden nur fehlerfreie \u00c4nderungsdatens\u00e4tze aus den Tabellen des Schemas <strong>L1<\/strong> in den Tabellen des Schemas <strong>L2<\/strong> historisiert. Neue , ge\u00e4nderte und gel\u00f6schte Datens\u00e4tze werden zus\u00e4tzlich mit einem Flag versehen, das anzeigt, dass diese noch in das Zielsystem zu \u00fcbernehmen sind. Werden auch die Daten des Schemas <strong>L2<\/strong> historisiert, sind diese nie zu l\u00f6schen und sollten \u00fcber einen Wartungsprozess gesichert werden. Damit kann jederzeit nachvollzogen werden, wann welcher Datensatz ge\u00e4ndert wurden.<\/p>\n\n\n\n<p>Die erforderlichen Prozeduren f\u00fcr die Historisierung von Daten in den Tabellen des Schemas <strong>L2<\/strong> sind manuell zu entwickeln.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ArchitectureLoad\">Laden<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"360\" src=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-9-1024x360.png\" alt=\"Loading data into the target system\" class=\"wp-image-1525\" srcset=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-9-1024x360.png 1024w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-9-300x105.png 300w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-9-768x270.png 768w, https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-9.png 1082w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Die transformierten und gepr\u00fcften Daten aus dem Schema <strong>L2<\/strong> k\u00f6nnen nun mit einer Technologie der Wahl in das Zielsystem geladen werden. Die zu ladenden \u00c4nderungsdaten k\u00f6nnen \u00fcber ein Flag, das angibt, ob der Datensatz bereits in das Zielsystem geladen wurde oder nicht, identifiziert werden. Datens\u00e4tze, die erfolgreich in das Zielsystem geladen wurden, sind entsprechend markieren.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Verwandte Artikel<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/sql.marcus-belz.de\/?p=1246\" data-type=\"post\" data-id=\"1246\">Datenqualit\u00e4t in einem ETL-Prozess<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/Datenqualit\u00e4t \/\/ Grundlagen der Typ-Konvertierung mit T-SQL\">Datenqualit\u00e4t \/\/ Grundlagen der Typ-Konvertierung mit T-SQL<\/a><\/li>\n<\/ul>\n\n\n\n<p> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dieser Artikel geh\u00f6rt zu der Artikelserie Datenqualit\u00e4t in einem ETL-Prozess, in der ein Design Pattern vorgestellt wird, das extrahierte Daten pr\u00fcft, behandelt und schlechte Daten von der weiteren Verarbeitung ausschlie\u00dft. Ein wesentlicher Baustein des Design-Patterns ist die Aufteilung des ETL-Prozesses <a href=\"https:\/\/sql.marcus-belz.de\/?p=1268\" class=\"read-more\">Read More &#8230;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,5],"tags":[44,36,37,39,31,41,43,38,10,42],"class_list":["post-1268","post","type-post","status-publish","format-standard","hentry","category-all-languages","category-german","tag-architecture","tag-data-cleansing","tag-data-quality","tag-design-pattern","tag-etl-process","tag-extract","tag-load","tag-sql","tag-t-sql","tag-transform"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Design Pattern \/\/ Architektur eines ETL-Prozesses - Just another SQL blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/sql.marcus-belz.de\/?p=1268\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Design Pattern \/\/ Architektur eines ETL-Prozesses - Just another SQL blog\" \/>\n<meta property=\"og:description\" content=\"Dieser Artikel geh\u00f6rt zu der Artikelserie Datenqualit\u00e4t in einem ETL-Prozess, in der ein Design Pattern vorgestellt wird, das extrahierte Daten pr\u00fcft, behandelt und schlechte Daten von der weiteren Verarbeitung ausschlie\u00dft. Ein wesentlicher Baustein des Design-Patterns ist die Aufteilung des ETL-Prozesses Read More ...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/sql.marcus-belz.de\/?p=1268\" \/>\n<meta property=\"og:site_name\" content=\"Just another SQL blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-02-23T16:33:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-03-01T12:59:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1024x251.png\" \/>\n<meta name=\"author\" content=\"marcus\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Geschrieben von\" \/>\n\t<meta name=\"twitter:data1\" content=\"marcus\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"27\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268\"},\"author\":{\"name\":\"marcus\",\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/#\\\/schema\\\/person\\\/7b46a383907dc48ca44fae32ceb24744\"},\"headline\":\"Design Pattern \\\/\\\/ Architektur eines ETL-Prozesses\",\"datePublished\":\"2024-02-23T16:33:31+00:00\",\"dateModified\":\"2024-03-01T12:59:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268\"},\"wordCount\":5421,\"image\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/sql.marcus-belz.de\\\/wp-content\\\/uploads\\\/2024\\\/02\\\/image-1024x251.png\",\"keywords\":[\"Architecture\",\"Data Cleansing\",\"Data Quality\",\"Design Pattern\",\"ETL-Process\",\"Extract\",\"Load\",\"SQL\",\"T-SQL\",\"Transform\"],\"articleSection\":[\"All Languages\",\"German\"],\"inLanguage\":\"de\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268\",\"url\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268\",\"name\":\"Design Pattern \\\/\\\/ Architektur eines ETL-Prozesses - Just another SQL blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/sql.marcus-belz.de\\\/wp-content\\\/uploads\\\/2024\\\/02\\\/image-1024x251.png\",\"datePublished\":\"2024-02-23T16:33:31+00:00\",\"dateModified\":\"2024-03-01T12:59:26+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/#\\\/schema\\\/person\\\/7b46a383907dc48ca44fae32ceb24744\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268#primaryimage\",\"url\":\"https:\\\/\\\/sql.marcus-belz.de\\\/wp-content\\\/uploads\\\/2024\\\/02\\\/image.png\",\"contentUrl\":\"https:\\\/\\\/sql.marcus-belz.de\\\/wp-content\\\/uploads\\\/2024\\\/02\\\/image.png\",\"width\":1077,\"height\":264},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?p=1268#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/sql.marcus-belz.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Design Pattern \\\/\\\/ Architektur eines ETL-Prozesses\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/#website\",\"url\":\"https:\\\/\\\/sql.marcus-belz.de\\\/\",\"name\":\"Just another SQL blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/sql.marcus-belz.de\\\/#\\\/schema\\\/person\\\/7b46a383907dc48ca44fae32ceb24744\",\"name\":\"marcus\",\"url\":\"https:\\\/\\\/sql.marcus-belz.de\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Design Pattern \/\/ Architektur eines ETL-Prozesses - Just another SQL blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/sql.marcus-belz.de\/?p=1268","og_locale":"de_DE","og_type":"article","og_title":"Design Pattern \/\/ Architektur eines ETL-Prozesses - Just another SQL blog","og_description":"Dieser Artikel geh\u00f6rt zu der Artikelserie Datenqualit\u00e4t in einem ETL-Prozess, in der ein Design Pattern vorgestellt wird, das extrahierte Daten pr\u00fcft, behandelt und schlechte Daten von der weiteren Verarbeitung ausschlie\u00dft. Ein wesentlicher Baustein des Design-Patterns ist die Aufteilung des ETL-Prozesses Read More ...","og_url":"https:\/\/sql.marcus-belz.de\/?p=1268","og_site_name":"Just another SQL blog","article_published_time":"2024-02-23T16:33:31+00:00","article_modified_time":"2024-03-01T12:59:26+00:00","og_image":[{"url":"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1024x251.png","type":"","width":"","height":""}],"author":"marcus","twitter_card":"summary_large_image","twitter_misc":{"Geschrieben von":"marcus","Gesch\u00e4tzte Lesezeit":"27\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/sql.marcus-belz.de\/?p=1268#article","isPartOf":{"@id":"https:\/\/sql.marcus-belz.de\/?p=1268"},"author":{"name":"marcus","@id":"https:\/\/sql.marcus-belz.de\/#\/schema\/person\/7b46a383907dc48ca44fae32ceb24744"},"headline":"Design Pattern \/\/ Architektur eines ETL-Prozesses","datePublished":"2024-02-23T16:33:31+00:00","dateModified":"2024-03-01T12:59:26+00:00","mainEntityOfPage":{"@id":"https:\/\/sql.marcus-belz.de\/?p=1268"},"wordCount":5421,"image":{"@id":"https:\/\/sql.marcus-belz.de\/?p=1268#primaryimage"},"thumbnailUrl":"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1024x251.png","keywords":["Architecture","Data Cleansing","Data Quality","Design Pattern","ETL-Process","Extract","Load","SQL","T-SQL","Transform"],"articleSection":["All Languages","German"],"inLanguage":"de"},{"@type":"WebPage","@id":"https:\/\/sql.marcus-belz.de\/?p=1268","url":"https:\/\/sql.marcus-belz.de\/?p=1268","name":"Design Pattern \/\/ Architektur eines ETL-Prozesses - Just another SQL blog","isPartOf":{"@id":"https:\/\/sql.marcus-belz.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/sql.marcus-belz.de\/?p=1268#primaryimage"},"image":{"@id":"https:\/\/sql.marcus-belz.de\/?p=1268#primaryimage"},"thumbnailUrl":"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image-1024x251.png","datePublished":"2024-02-23T16:33:31+00:00","dateModified":"2024-03-01T12:59:26+00:00","author":{"@id":"https:\/\/sql.marcus-belz.de\/#\/schema\/person\/7b46a383907dc48ca44fae32ceb24744"},"breadcrumb":{"@id":"https:\/\/sql.marcus-belz.de\/?p=1268#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/sql.marcus-belz.de\/?p=1268"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/sql.marcus-belz.de\/?p=1268#primaryimage","url":"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image.png","contentUrl":"https:\/\/sql.marcus-belz.de\/wp-content\/uploads\/2024\/02\/image.png","width":1077,"height":264},{"@type":"BreadcrumbList","@id":"https:\/\/sql.marcus-belz.de\/?p=1268#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/sql.marcus-belz.de\/"},{"@type":"ListItem","position":2,"name":"Design Pattern \/\/ Architektur eines ETL-Prozesses"}]},{"@type":"WebSite","@id":"https:\/\/sql.marcus-belz.de\/#website","url":"https:\/\/sql.marcus-belz.de\/","name":"Just another SQL blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/sql.marcus-belz.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/sql.marcus-belz.de\/#\/schema\/person\/7b46a383907dc48ca44fae32ceb24744","name":"marcus","url":"https:\/\/sql.marcus-belz.de\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=\/wp\/v2\/posts\/1268","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1268"}],"version-history":[{"count":9,"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=\/wp\/v2\/posts\/1268\/revisions"}],"predecessor-version":[{"id":1533,"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=\/wp\/v2\/posts\/1268\/revisions\/1533"}],"wp:attachment":[{"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1268"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1268"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sql.marcus-belz.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1268"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}