Unser Newsletter rund um technische Themen,
das Unternehmen und eine Karriere bei uns.

9 Minuten Lesezeit (1899 Worte)

Da steht ein Elefant im Raum: PostgreSQL vs. Oracle

„Wenn ein Elefant im Raum steht, dann sollte man ihn vorstellen.“ – Der Elefant hört in unserem Fall auf den Namen „Slonik“ und ist das Logo der OpenSource-Datenbank PostgreSQL. „Slonik“ ist russisch und steht für „kleiner Elefant“. Mehr und mehr wird dieser Elefant zu einer Alternative auf dem Datenbank-Markt. Immer mehr und mehr Oracle-Anwender ziehen einen Wechsel Richtung PostgreSQL in Erwägung. Grund genug, einmal einen Blick auf die Unterschiede zwischen den beiden RDBMS, Oracle und PostgreSQL, zu werfen.

Der Hauptgrund für die Beschäftigung mit dem Thema „PostgreSQL“ sind sicher die Kosten. Oracle kostet Lizenzkosten und jährliche Supportkosten. PostgreSQL ist in der OpenSource-Variante kostenlos verfügbar. Und damit haben wir schon den größten Unterschied zwischen beiden Datenbanksystemen. Aber ist PostgreSQL wirklich kostenlos? Wer eine der kommerziellen Varianten einsetzt oder wer kommerziellen Support einkauft, der hat natürlich auch bei PostgreSQL Kosten. Und neben den Software- und Wartungskosten, kommen die Ausgaben für Schulungen, ggf. Migrationskosten usw. noch dazu. Die Aussage „PostgreSQL ist günstiger als Oracle“ gilt in dieser Pauschalität nicht, das hat ja auch schon Daniel Westermann im Interview im RedStack-Magazin 6/2022 bestätigt.

Wenn man auf den kommerziellen Support verzichtet, dann hat man „nur“ den Support durch die Community via Mailing-Listen. Und da gilt – wenn man fundierte Fragen stellt und sich an die Netiquette hält – durchaus: „hier werden sie geholfen“. Ob der PostgreSQL-Support – kommerziell oder in der Community – dann besser ist als der Oracle-Support, über den in den DOAG-Umfragen die Mitglieder regelmäßig klagen, das muss dann jeder selbst entscheiden.

Sehr wichtig: die Community

Generell gilt: Ohne die Community geht bei PostgreSQL nichts. Die Community sorgt für Support, die Community entscheidet über die Features in den neuen Versionen usw. Die Community sorgt dafür, dass PostgreSQL lebt und weiterentwickelt wird. Und wenn man der Mentalität „Open Source ist kostenlos“ folgt und nichts in und für die Community tut, dann wird man dem Open-Source-Prinzip nicht denn gerecht. Denn wenn alle nur konsumieren und sich nicht engagieren, dann geht es irgendwann nicht mehr weiter. Denn die Community lebt vom Mitmachen. Dazu muss man keinen C-Code für PostgreSQL schreiben. Es gibt vielfältige Möglichkeiten: Testumgebungen bereitstellen, neue Features testen, an der Dokumentation mitarbeiten, Wissen in Vorträgen oder Artikeln teilen, Konferenzen organisieren oder unterstützen, usw. Kurzum, wie immer gilt auch hier: Wer etwas will, findet Wege!

Und wie sieht es auf technischer Ebene aus? Da gibt es viele Gemeinsamkeiten: Beides sind relationale Datenbank-Systeme und die Relationen-Algebra, die Codd'schen Regeln und die ACID-Regeln sorgen für einen engen Spielraum für die Implementierungen. Auch die SQL-Standards setzen Grenzen. Allerdings erfüllt keines der beiden Systeme die SQL-Standards komplett. Aber wer eine Datenbank als „dummen Datenspeicher“ betreibt und sämtliche Logik in der Applikation hält, für den sind die Unterschiede marginal.

PostgreSQL ist schlanker

Beginnen wir mit der Installation: Eine Oracle-Installation belegt etwa 9 GB. Bei PostgreSQL sind es etwa 70 MB. Allerdings ist PostgreSQL dabei auch recht minimalistisch. Dinge, die bei Oracle dabei sind, sind bei PostgreSQL als Tools oder Erweiterungen verfügbar. Fast für alles, was einem fehlen könnte, gibt es eine Erweiterung. Diese Erweiterbarkeit ist Fluch und Segen zugleich. Fluch, weil man suchen muss. Weil man sich entscheiden muss: Nehme ich Backup-Tool A oder B? Und wenn es dann um ein PostgreSQL-Upgrade geht, dann muss der DBA selbst schauen, ob es für die Erweiterungen neue Versionen gibt, die mit der neuen Datenbank-Version kompatibel sind. Das alles sorgt für Aufwand und damit auch für Kosten. Und man hat als Administrator dann auch mehr Verantwortung, als wenn man sich auf ein weitestgehend „vorkonfiguriertes Paket“ wie Oracle verlässt. Aber die Medaille hat wie immer zwei Seiten, denn es kann auch ein Segen sein: Man hat mehr Freiheiten und kann sich „sein“ PostgreSQL so zusammenstellen, wie man es denn benötigt.

Wenn man nach der Installation eine Datenbank anlegt, dann braucht man bei Oracle mehr als 4 GB Platz. Ein leerer PostgreSQL-Cluster braucht ca. 40 MB und eine Datenbank, kommen noch 2 MB dazu. Und auch wenn man sich die Prozessliste anschaut, dann ist PostgreSQL schlanker. Während es bei Oracle inzwischen mehr als 40 Hintergrundprozesse sind, sind es bei einem einfachen PostgreSQL weniger als zehn. Zugegebenermaßen kommen durch Erweiterungen teilweise noch Prozesse dazu, aber insgesamt gilt, dass PostgreSQL wesentlich ressourcenfreundlicher ist als Oracle.

Wenn man mit verschiedenen Datenbanken arbeitet, dann ist eine Begriffsvielfalt unvermeidlich. Und so ist es auch beim Vergleich von Oracle mit PostgreSQL. Vergleichbare Funktionalität hat unterschiedliche Namen und die gleichen Begriffe bezeichnen unterschiedliche Funktionalität.

Während man bei Oracle von „Tabellen“ und „Indizes“ spricht, sind es bei PostgreSQL erst einmal „Relationen“. Im Alltag redet man natürlich auch bei PostgreSQL von Tabellen, Indizes, Datensätzen und Spalten, aber in der Dokumentation und in den Systemtabellen und -views findet man oft die Begriffe „Relation“, „Tupel“ und „Attribute“. Diese Begriffe kommen aus der Datenbanktheorie. PostgreSQL orientiert sich aufgrund seiner universitären Herkunft oft an diesen akademischen Begriffen.

Wenn man bei Oracle bei „Cluster“ wohl an den Real-Application-Cluster denkt, dann ist PostgreSQL ein „Cluster“ eine „Sammlung von Datenbanken, die von einer PostgreSQL-Instanz verwaltet wird“.

Auch der Begriff „Tablespace“ hat bei PostgreSQL eine andere Bedeutung. Bei Oracle gilt:  Ein Tablespace besteht aus Datendateien und in diesen Dateien liegen die Objekte. Bei PostgreSQL ist ein „Tablespace“ nur ein „Alias“ für ein Verzeichnis. In diesem Verzeichnis liegen dann pro Relation je nach Größe eine oder mehrere Dateien. Dieses unterschiedliche Konzept ist auch der Grund dafür, dass zusätzliche Tablespaces bei PostgreSQL seltener verwendet werden als bei Oracle.

Benutzer, Rollen, Schemata

Drei Begriffe, viele Ähnlichkeiten. Es gibt aber Unterschiede. Bei Oracle sind „Schemata“ „Benutzer mit Objekten“. Getrennt davon gibt es Rollen als Sammlung von Rechten. Bei PostgreSQL gilt das auch, aber Rollen und Benutzer teilen sich den gleichen Namensraum. Ein „Benutzer“ ist eine „Rolle mit Login-Recht“. Und zusätzlich zu Benutzer und Rollen, die clusterweit definiert sind, gibt es „Schemata“ auf Datenbank-Ebene. Jedes Schema hat einen Benutzer als Eigentümer. In den meisten Fällen gibt es ein 1:1-Mapping, es sind aber separate Namensräume. Das kann durchaus für Verwirrung sorgen.

postgres=# create user scott_usr password 'tiger';

CREATE ROLE 

Listing 1: „Create User" wird – im ersten Moment irreführend mit „create role" quittiert 

postgres=# create schema scott_schema authorization scott_usr;

CREATE SCHEMA 

Listing 2: Schemaname und der zugehörige Eigentümer können sich unterscheiden

Transaktionen: ORA-1555" versus Table Bloat"

Unterschiede gibt es auch bei den Transaktionen. Nicht im ganz großen Sinne, denn beide Datenbanken befolgen die ACID-Regeln, aber bei der Implementierung. Während es bei Oracle die Redolog-Dateien gibt, die zyklisch geschrieben werden, gibt es bei PostgreSQL WAL-Segmente. „WAL“ steht für Write-Ahead-Log und meint die gleiche Funktionalität; es sind die Transaktionslogs. Dabei werden diese Dateien nicht zyklisch überschrieben, sondern – grob gesagt – von PostgreSQL in einem gewissen Rahmen (Plattenplatz) verwaltet und auch wiederverwendet.

Auch beim Thema „Undo“ gehen beide Datenbanken unterschiedliche Wege. Während wir bei Oracle die „Undo“-Tablespaces haben, löst PostgreSQL das Problem der Lesekonsistenz auf andere, etwas einfachere Weise. Jeder Datensatz hat zwei Spalten, xmin und xmax, die den Gültigkeitszeitraum (in Transaktions-IDs) eines Datensatzes angeben. Beispielsweise wird bei einem Update xmax als Obergrenze gesetzt und eine (geänderte) Kopie des Datensatzes angelegt, die dann die aktuelle Version darstellt. Vorteil dieses Verfahrens ist, dass PostgreSQL-Benutzer kein Pendant zum Fehler „ORA-1555 Snapshot too old“ kennen, der immer dann kommt, wenn Oracle aus den Undo-Daten das lesekonsistente Bild eines Datensatzes nicht mehr erstellen kann. Nachteil ist, dass DML die Tabellen größer macht. Vereinfacht formuliert verdoppelt ein UPDATE auf alle Datensätze die Größe einer Tabelle. Diese Verhalten wird auch als „Table Bloat“ bezeichnet. Daher sollte man regelmäßig aufräumen, d. h. alte Datensatz-Versionen, die von keiner Sitzung mehr benötigt werden, löschen. Dazu gibt es den VACUUM-Befehl und den autovacuum-Daemon, der diese Arbeit automatisch im Hintergrund erledigen kann.

Auch bei Transaktionsfehlern gehen beide Datenbanken einen unterschiedlichen Weg. Wenn bei Oracle ein Befehl auf einen Fehler läuft, dann wird nur dieser Befehl nicht ausgeführt. Bei PostgreSQL wird hingegen die ganze Transaktion zurückgerollt und erst nach einem Transaktionsende („ROLLBACK“) geht es weiter. Dieser Unterschied kann dazu führen, dass man bei migrierten Applikationen die Fehlerbehandlung anpassen muss.

postgres# update scott.emp set name='KONG' where name='KING';

UPDATE 1

postgres# select 1/0;

ERROR: 22012: division by zero

LOCATION: int4div, int.c:846

postgres# update scott.emp set salary=salary+100 where empno=7839;

ERROR: 25P02: current transaction is aborted, commands ignored until end of transaction block

LOCATION: exec_simple_query, postgres.c:1116

postgres# commit;

ROLLBACK 

Listing 3: Verhalten von PostgreSQL bei Fehlern in einer Transaktion – nur ROLLBACK erlaubt

Ein manchmal recht angenehmer Unterschied von PostgreSQL zu Oracle ist das „transaktionale DDL“: Man kann DDL mittels ROLLBACK zurückrollen. Das kann z. B. bei fehlgeschlagenen Applikationsupgrades sehr helfen. 

Datum – mit oder ohne Uhrzeit?

PostgreSQL hat generell mehr Datentypen als Oracle. So gibt es dort z. B. den Datentyp boolean, der bei Oracle erst für Version 23c angekündigt ist. Auch der Typ „DOMAIN“, kurz gesagt ein Datentyp mit verknüpfter Constraint, den es in PostgreSQL schon länger gibt, soll mit Oracle 23c kommen. Oder den Typ tsrange, der die Arbeit mit Zeiträumen erleichtert. Einen feinen Unterschied gibt es beim Datentyp DATE: bei Oracle mit Uhrzeit; bei PostgreSQL ohne Uhrzeit. Spätestens, wenn man bei einer Migration die Datentypen 1:1 übernimmt, dann führt das in diesem Fall zu Problemen. Ein Unterschied mit Aha-Erlebnis zeigt sich auch bei numerischen Typen, wenn man sie dividiert: 

postgres=# select 5/2,5.0/2;

?column? | ?column?

----------+--------------------

2 | 2.5000000000000000

(1 row) 

Listing 4: „Integer" durch „Integer" ergibt „Integer", „Float" durch „Integer" ergibt „Float"

Bei Oracle ergeben beide Rechnungen „2.5".

Hochverfügbarkeit

Beim Begriff „Hochverfügbarkeit“ kommen bei Oracle sofort die Begriffe „Real Application Cluster“, „(Active) DataGuard“ und „GoldenGate“ ins Spiel. Bei PostgreSQL basiert Hochverfügbarkeit auf Replikation. Dabei gilt es die gleichen Formen der Standby-Datenbank wie bei Oracle. „Active DataGuard“, bei PostgreSQL „Hot-Standby“ genannt, bekommt man kostenfrei dazu. Für komplexere HA-Systeme wird bei PostgreSQL häufig Patroni (https://github.com/zalando/patroni) eingesetzt. Patroni ist aber keine vollständige Anleitung für PostgreSQL-Hochverfügbarkeit, sondern eine Vorlage; eine Blaupause. Das gibt dem DBA mehr Freiheiten bei der Implementierung einer konkreten Lösung, aber auch mehr Verantwortung. 

Der kleine Unterschied

Wenn man sich mit beiden Datenbanken beschäftigt oder sogar eine Datenbank inklusive Applikation von Oracle nach PostgreSQL migriert, dann stößt man schnell auf die Verhaltensunterschiede der beiden Datenbanken. Neben den oben geschilderten Unterschieden im Transaktionsverhalten gibt es noch einige mehr. Hier ein paar Beispiele:

Ein Klassiker dabei ist der unterschiedliche Umgang mit NULL-Strings. Oracle behandelt NULL und leere Strings gleich:

SQL> select 'DOAG'||NULL from dual;

'DOA

----

DOAG 

Listing 5: Verknüpfung mit NULL-Strings in Oracle

PostgreSQL hingegen verarbeitet NULL-Strings ANSI-SQL-konform: 

postgres=# select 'DOAG'||NULL;

?column?

----------

[NULL]

(1 row) 

Listing 6: Verknüpfung mit NULL-Strings in PostgreSQL

Da NULL-Strings bei Verknüpfungen sicher nicht der Normalfall sind, ist so ein Unterschied bei Tests nach Migrationen nicht so einfach zu entdecken. Ein kleiner, aber lästiger Unterschied zwischen beiden Datenbanken ist die Tatsache, dass Objektnamen bei Oracle standardmäßig in Großschrift sind, während es bei PostgreSQL Kleinbuchstaben sind. Man muss also mit Anführungszeichen arbeiten. 

Ab jetzt nur noch PostgreSQL?

Wie immer gilt in der Realität: Es gibt kein schwarz oder weiß. Es gibt kein „besser oder schlechter“, sondern nur ein: „Für ein Umfeld oder eine Applikation ist diese Datenbank besser geeignet als eine andere“. Viele Oracle-Anwender setzen bei neuen Projekten auf PostgreSQL, um so Erfahrungen zu sammeln. Bestehende Systeme werden eher seltener migriert, insbesondere wenn es große und kritische Systeme gibt. Und so wird es ein Miteinander geben. Da es immer mehr Datenbank-Anwendungen gibt, ist in der Datenbank-Welt auch Platz für mehrere Datenbanken. Und das ist auch gut für die Anwender, denn wie immer gilt: Konkurrenz belebt das Geschäft. 

Principal Consultant bei ORDIX

 

Kommentare

Derzeit gibt es keine Kommentare. Schreibe den ersten Kommentar!
Freitag, 27. Dezember 2024

Sicherheitscode (Captcha)

×
Informiert bleiben!

Bei Updates im Blog, informieren wir per E-Mail.