Die Aus­wahl der ver­wen­de­ten Daten­bank­sys­teme ist von weit­rei­chen­der Bedeu­tung im Hin­blick auf Ent­wick­lung und War­tung der ver­wen­de­ten Appli­ka­tio­nen. Kürz­lich stel­len sich unse­rer Kun­den ver­mehrt die Frage, ob sie von Ora­cle nach Post­greSQL migrie­ren wol­len. Die Redu­zie­rung von Lizenz­kos­ten ist dabei ein wich­ti­ger Fak­tor. Wei­tere Punkte soll­ten bei der Ent­schei­dungs­fin­dung aber eben­falls gebüh­rend berück­sich­tigt wer­den, um die Vor- und Nach­teile einer Migra­tion abzu­wä­gen. In die­sem Blog schil­dern wir unsere Erfah­rung einer Migra­tion von Ora­cle nach Post­greSQL mit Infor­ma­tica PowerCenter.

Aus­gangs­lage

Der Kunde hat sich ent­schie­den, einen Ora­cle-Ser­ver aus­ser Betrieb zu neh­men und die Daten­ban­ken nach Post­greSQL zu migrie­ren. Die Migra­tion geschieht in meh­re­ren Etap­pen, um den lau­fen­den Betrieb nicht zu gefähr­den. Als ETL-Tool kommt Infor­ma­tica Power­Cen­ter zum Ein­satz. Andere Appli­ka­tio­nen lau­fen wei­ter­hin auf Ora­cle. Somit beinhal­tet die Migra­tion auch das Ein­bin­den der neuen Post­reSQL Tabel­len in die bestehen­den Systeme.

Daten­ty­pen in Ora­cle und PostgreSQL

Die alten Ora­cle-Tabel­len ent­hal­ten Pri­mär- und Fremd­schlüs­sel im Daten­typ RAW. Die­ser wird bei der Migra­tion nicht über­nom­men, son­dern in Post­greSQL durch NUMERIC ersetzt. Das heisst, dass die Schlüs­sel bei der Migra­tion neu gene­riert werden.

Text­fel­der vom Typ VARCHAR2(n) wer­den in Post­greSQL auf den Typ VARCHAR(n) oder TEXT gelegt. Bei TEXT ist dabei neu Länge unli­mi­tiert, ver­gleich­bar zu CLOB in Ora­cle. Damit bei die­sen Fäl­len die Infor­ma­tica-Ses­sion den Buf­fer nicht zu gross ansetzt, pas­sen wir die Text­länge in den Infor­ma­tica-Tar­gets auf die Länge der Sources an. 

Ora­cle kennt kei­nen boolean Daten­typ. Statt­des­sen wer­den binäre Daten typi­scher­weise als NUMBER(1, 0) gespei­chert. Infor­ma­tica Power­cen­ter unter­stützt eben­falls kei­nen boolean Daten­typ in Trans­for­ma­tio­nen. Bool- respek­tive Bit-Columns wer­den im Source-Qua­li­fier als String impor­tiert. Den­noch kann man in Post­greSQL Bool-Columns schrei­ben. Wie erwar­tet, wird dabei 0 auf false und 1 auf true gemappt. Inter­es­sant ist dabei, dass deci­mal Daten­ty­pen eben­falls nach bool kon­ver­tiert wer­den kön­nen. Wir stel­len dabei das fol­gende Ver­hal­ten fest: 0 <= x < 1 wird zu false und 1 <= x < 2 zu true. Alle ande­ren Werte resul­tie­ren in einem Fehler. 

Bei Datums­fel­dern muss man beach­ten, dass DATE in Ora­cle die Zeit mit einer Genau­ig­keit von Sekun­den beinhal­tet. In Post­greSQL ist DATE jedoch nur das Datum ohne Zeit. Wenn die Zeit mit Sekun­den benö­tigt wird, muss in Post­greSQL TIMESTAMP(0) ver­wen­det wer­den. Bei höhe­rer Genau­ig­keit bis Mikro­se­kun­den wird in bei­den Sys­te­men TIMESTAMP verwendet.

Ora­clePost­greSQL
VARCHAR2(n)VARCHAR(n)
CLOBTEXT
NUMBER(p, s)NUMERIC(p, s)
NUMBER(1, 0), nur Werte von 0 und 1BOOL
DATE, nur Datum ohne ZeitDATE
DATE, Datum und ZeitTIMESTAMP(0)
TIMESTAMPTIMESTAMP
Tabelle 1. Über­sicht der wich­tigs­ten Daten­ty­pen bei der Migra­tion von Ora­cle nach Post­greSQL (unvoll­stän­dig)

Code-Page Ver­wir­rung in Informatica

Die Ora­cle und Post­greSQL Daten­ban­ken ver­wen­den beide die UTF‑8 Code­page. Infor­ma­tica ist eben­falls auf UTF‑8 ein­ge­stellt. Trotz­dem gab es einige Über­ra­schun­gen bei der Migra­tion. Wurde der ODBC-Kon­nek­tor für Post­greSQL in Infor­ma­tica auf UTF‑8 ein­ge­stellt, wur­den alle mul­ti­byte Zei­chen nicht kor­rekt ver­ar­bei­tet, also Zei­chen wie «ö» oder «é». Die ver­meint­li­che Lösung war, den Kon­nek­tor auf ISO 8859–1 ein­zu­stel­len. Also war die Code­page des Kon­nek­tors anders als die der Quelle- und Zieldatenbanken.

Das führte jedoch zu einem wei­te­ren Pro­blem. Beim Schrei­ben ins Ziel hat Infor­ma­tica Texte mit einer Länge von einem Byte pro Zei­chen behan­delt. Bei Ein­trä­gen in der Quelle, wo die Text­länge ganz oder nahezu aus­ge­schöpft war, wurde der Text vor dem Schrei­ben ins Ziel gekürzt. Um die­ses Ver­hal­ten zu ver­hin­dern, musste in der Tar­get-Defi­ni­tion die Länge aller Text­fel­der erhöht wer­den. Zur Sicher­heit haben wir die Länge gegen­über der Defi­ni­tion auf der Tabelle ver­dop­pelt. So könnte auch ein String, der aus­schliess­lich aus zwei­by­ti­gen Zei­chen besteht kor­rekt ver­ar­bei­tet werden.

Durch das Umstel­len des Kon­nek­tors auf ISO 8859–1 und dem gleich­zei­ti­gen Erhö­hen der Feld­länge in der Infor­ma­tica Tar­get-Defi­ni­tion wurde der Gross­teil der Texte kor­rekt ver­ar­bei­tet. In die umge­kehrte Rich­tung von Post­greSQL nach Ora­cle waren keine manu­el­len Anpas­sun­gen an der Tar­get-Defi­ni­tion nötig. Beim Lesen ab Post­greSQL und dem Schrei­ben in Ora­cle mit dem Post­greSQL Kon­nek­tor in ISO 8859–1 wur­den Son­der­zei­chen kor­rekt verarbeitet.

Nach umfang­rei­chen Tests zeigte sich jedoch, dass die­ser Work­around für einige Zei­chen nicht funk­tio­nierte. Zum Bei­spiel wurde das fran­zö­si­sche «œ» (U+0153) als «S» aus­ge­ge­ben. Nach wei­te­ren Ana­ly­sen stellte sich her­aus, dass das Set­ting für die ODBC-Kon­nek­to­ren im odbc.ini File auf ISO_8859‑1:1987 ein­ge­stellt war (IANAAppCodePage=4). Die Lösung ist, sowohl den ODBC-Kon­nek­tor als auch die Code­page im odbc.ini File auf UTF‑8 ein­zu­stel­len (IANAAppCodePage=106).

Fremd­schlüs­sel

Auf­grund des Änderns der Schlüs­sel­ty­pen müs­sen die Pri­mär- und Fremd­schlüs­sel neu erstellt wer­den. Um die Fremd­schlüs­sel­be­zie­hun­gen zu erhal­ten, wer­den die alten Schlüs­sel vom Typ RAW zwi­schen­ge­spei­chert und auf die neuen Schlüs­sel gemappt. Die gewählte Lösung hängt von der Kom­ple­xi­tät des Daten­mo­dells ab.

In einem ein­fa­chen Modell mit einer Fact-Tabelle und meh­re­ren Dimen­sio­nen wird zuerst die Fact-Tabelle migriert. Dabei wer­den die RAW-IDs als Hex-String in die neuen Tabel­len geschrie­ben und gleich­zei­tig die neuen NUMERIC IDs mit einer Post­greSQL Sequence gene­riert. Danach kann für die Dimen­sion-Tabel­len der neue Fremd­schlüs­sel mit­tels Lookup auf die RAW-ID ermit­telt wer­den. Der Vor­teil die­ser Vari­ante ist, dass sie ein­fach zu imple­men­tie­ren ist. Aller­dings wer­den die Spal­ten mit der alten ID nach der Migra­tion obsolet.

Für ein grös­se­res Daten­mo­dell mit vie­len Fremd­schlüs­sel­be­zie­hun­gen inklu­sive Selbst­re­fe­ren­zen kommt die­ser Ansatz nicht infrage. Statt­des­sen erstel­len wir eine Map­ping-Tabelle, in die wir zuerst alle alten IDs als Hex-String schrei­ben und dabei gleich­zei­tig mit einem Infor­ma­tica Sequence-Gene­ra­tor die neue ID erstel­len. Bei der eigent­li­chen Migra­tion kann die neue ID aus die­ser Tabelle mit­tels Lookup ermit­telt werden.

Mapping von Oracle nach PostgreSQL
Abbil­dung 1. Infor­ma­tica Power­Cen­ter Map­ping von Ora­cle nach Post­greSQL mit Ände­rung des Schlüsseltyps

Ver­ar­bei­tung im DWH

Das DWH wird wei­ter­hin auf Ora­cle betrie­ben. Einige der migrier­ten Tabel­len wer­den im DWH in einer his­to­ri­sier­ten Form gespei­chert. So ste­hen Daten, die in der Quelle gelöscht wer­den, wei­ter­hin zur Ver­fü­gung. Um die Kon­sis­tenz zu wah­ren, müs­sen wir auch in die­sen Tabel­len die alte binäre ID durch eine neue nume­ri­sche ersetz­ten. Dazu ver­wen­den wir den­sel­ben Sequence-Gene­ra­tor aus Informatica.

Ansons­ten wer­den die IDs im DWH nur für Joins ver­wen­det. Somit müs­sen für die wei­tere Ver­ar­bei­tung in Infor­ma­tica ledig­lich die Daten­ty­pen ange­passt werden.

Zusam­men­fas­sung

Das hier beschrie­bene Bei­spiel zeigt, dass eine schein­bar ein­fa­che Migra­tion von Ora­cle nach Post­greSQL eini­ges an Auf­wand ver­ur­sa­chen kann. Obwohl (ver­meint­lich) alle Sys­teme auf UTF‑8 ein­ge­stellt waren, hat­ten wir zuerst Pro­bleme mit der Ver­ar­bei­tung der Code­page. Die Details sind in die­sem Fall spe­zi­fisch für Infor­ma­tica Power­Cen­ter. Aber Feh­ler auf­grund der Code­page tre­ten lei­der oft auf, was eine umfas­sende Ana­lyse und Tests vor der Migra­tion nötig machen.

Unser Bei­spiel betrifft nicht eine 1:1 Migra­tion, son­dern einen Fall, wo gleich­zei­tig Daten­ty­pen ange­passt wer­den. Da es sich dabei um Schlüs­sel­fel­der han­delt, ist der Auf­wand dafür spe­zi­ell gross. Zuerst muss bei der Migra­tion die Kon­sis­tenz der Fremd­schlüs­sel­be­zie­hun­gen sicher­ge­stellt wer­den. Danach pas­sen wir die Ver­ar­bei­tung im DWH auf den neuen Daten­typ an.

Bei einer Migra­tion der Daten­bank­sys­teme ste­hen sich die lau­fen­den Kos­ten für Lizen­zen und War­tung den initia­len Kos­ten gegen­über. Die initia­len Kos­ten betref­fen dabei nicht nur das eigent­li­che «Ver­schie­ben» der Daten, son­dern ins­be­son­dere auch die Ver­ar­bei­tung ab dem neuen Sys­tem. Je nach ver­wen­de­ter ETL-Tech­no­lo­gie und ‑Logik kann der Auf­wand stark vari­ie­ren. Im bes­ten Fall sind keine wei­te­ren Anpas­sun­gen nötig (glei­che Daten ab neuer Quelle). Im schlech­tes­ten Fall müs­sen viele Ver­ar­bei­tungs­schritte auf das neue Quell­sys­tem ange­passt wer­den (neuer Syn­tax). Bei der Ent­schei­dung, ob man eine Migra­tion in Angriff neh­men will, müs­sen all diese Fak­to­ren berück­sich­tigt werden.

Erfah­ren Sie hier mehr über Lösun­gen im Bereich Data Manage­ment oder besu­chen Sie eines unse­rer kos­ten­lo­sen Web­i­nare.

Bild­quelle