Files
it-know-how/datenbanken/PostgreSQL/PostgreSQL Umstieg von Oracle SQL.md
T
2026-03-27 12:58:01 +01:00

346 lines
11 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Hier eine kompakte, praxisorientierte Übersicht zu PostgreSQL mit Fokus auf „Was ist anders als in Oracle?“ und „Was sollte ich vor dem Umstieg lernen?“.
---
## 1. Kurzüberblick & Gemeinsamkeiten
Gemeinsamkeiten (nur kurz, da dir das meiste vertraut ist):
- Relationales DBMS, SQL-basiert, ANSI-konform
- [[ACID-Transaktionen]], [[MVCC]], Isolation Levels
- Sequences, Views, [[Materialized Views]], Trigger, Stored Procedures/Functions
- Joins, Subselects, Window Functions, [[CTEs]] (`WITH`), etc.
- Rolle-/Rechtemodell, Schemas
---
## 2. Zentrale Unterschiede auf einen Blick
Die wichtigsten Lernfelder im Übergang von Oracle zu PostgreSQL:
1. **Namensräume & `search_path` statt Synonyme**
2. **Datentypen & Funktionalität (z.B. `NUMERIC`, `SERIAL`, `JSONB`, Arrays)**
3. **Sequences & Identity-Spalten**
4. **PL/pgSQL vs. PL/SQL (kein Paketkonzept)**
5. **MVCC-Implementierung & VACUUM/Autovacuum**
6. **DDL in Transaktionen, Auto-Commit-Verhalten**
7. **Index-Typen & Besonderheiten (GIN/GiST, Partial-, Expression-Indexe)**
8. **Partitionierung (deutlich anders als ältere Oracle-Partitioning-Konzepte)**
9. **Admin & Tools (psql, Konfigurationsparameter, Monitoring)**
---
## 3. Schemata, Namensauflösung & Synonyme
### Schemata & `search_path`
In PostgreSQL sind Schemata ähnlich wie in Oracle. Es gibt zusätzlich einen **`search_path`**, der festlegt, in welcher Reihenfolge Schemata nach Objekten durchsucht werden.
```sql
SHOW search_path;
SET search_path TO app, public;
```
Statt Synonymen (Oracle) wird oft mit `search_path` gearbeitet:
- Kein `CREATE SYNONYM` in PostgreSQL.
- Alternative: Views in einem „zentrale“ Schema, `search_path` setzen, oder `CREATE VIEW` als Abstraktionsschicht.
**Lernpunkt:** Überleg dir, wie du Synonyme ablöst meistens durch eine Kombination aus `search_path`, Views und ggf. konsistenter Schema-Namenskonvention.
---
## 4. Datentypen & SQL-Dialekt
### Wichtige Unterschiede bei Datentypen
- `NUMBER` → in der Regel `NUMERIC(p,s)` oder `INTEGER`, `BIGINT`.
- `VARCHAR2``VARCHAR(n)` oder `TEXT`. PostgreSQL hat keinen Unterschied zwischen `VARCHAR` und `VARCHAR2`.
- `DATE` in PostgreSQL enthält Datum **und Uhrzeit** (wie Oracle `DATE`). Für „reine“ Datumswerte: `date`, für Zeitpunkte mit Zeitzone: `timestamptz`.
- `CLOB`/`BLOB` → meist `TEXT` bzw. `BYTEA`.
- Zusätzliche Typen:
- `JSON`/`JSONB`
- Arrays (`integer[]`, `text[]` etc.)
- Geodaten (via Extension PostGIS)
- `UUID`, `Inet`, `CIDR` etc.
```sql
CREATE TABLE kunde (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(200),
email TEXT,
erstellt_am timestamptz DEFAULT now(),
daten JSONB
);
```
### Funktionen und Syntax-Details
- String-Konkatenation: `||` (wie Oracle).
- `NVL``COALESCE` (Standard); es gibt auch `NULLIF`.
- `DECODE``CASE WHEN ... THEN ... ELSE ... END`.
- `ROWNUM``LIMIT` / `OFFSET` oder Window Functions (`row_number()`).
- Kein „`FROM dual`“ nötig, du kannst einfach:
```sql
SELECT 1;
```
**Lernpunkt:** Zuordnen der wichtigsten Oracle-Funktionen zu PostgreSQL-Äquivalenten (`DECODE` → `CASE`, `NVL` → `COALESCE`, `ROWNUM` → `LIMIT`/Window).
---
## 5. Sequences & Identity-Spalten
In Oracle: `CREATE SEQUENCE ...` + Trigger oder `IDENTITY` in neueren Versionen.
In PostgreSQL gibt es mehrere Varianten:
- Klassische Sequence:
```sql
CREATE SEQUENCE myseq;
SELECT nextval('myseq');
```
- „Legacy“ Auto-Increment:
```sql
CREATE TABLE t (
id SERIAL PRIMARY KEY,
...
);
```
- Standardkonforme [[Identity Columns]] (empfohlen):
```sql
CREATE TABLE t (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
...
);
```
**Lernpunkt:** Umstieg auf `GENERATED AS IDENTITY` planen, `SERIAL` verstehen (ist syntaktischer Zucker für Sequence + Default).
---
## 6. PL/pgSQL vs. PL/SQL (Packages, Prozeduren, Funktionen)
### Kein Paketkonzept
PostgreSQL hat keine Packages wie Oracle (`package spec/body`). Stattdessen:
- Funktionen stehen „flach“ in einem Schema.
- Ähnliches Strukturieren über Namenskonventionen, Schemata, Extensions.
### PL/pgSQL
Syntax ähnlich PL/SQL, aber mit einigen Unterschieden:
```sql
CREATE OR REPLACE FUNCTION addiere(a int, b int)
RETURNS int
LANGUAGE plpgsql
AS $$
DECLARE
res int;
BEGIN
res := a + b;
RETURN res;
END;
$$;
```
Ab PostgreSQL 11 gibt es auch **Stored Procedures** (ohne Rückgabewert, aufrufbar mit `CALL`) im Unterschied zu Funktionen, die in SQL-Ausdrücke eingebettet werden können.
**Lernpunkte:**
- Unterschiede in Ausnahmebehandlung und Cursor-Syntax im Detail.
- Kein Paket-Overloading wie in Oracle Overloading geht, aber ohne Packages.
- Migration von Package-Variablen: oft durch Tabellen, Konfigurationstabellen oder `SET LOCAL` + GUC-Parameter ersetzen.
---
## 7. Transaktionen, MVCC & Locks
### MVCC-Implementierung
Beide nutzen MVCC, aber die Implementierung ist anders:
- PostgreSQL speichert mehrere Versionen von Zeilen (Tuples) im Heap.
- Gelöschte/veraltete Versionen werden nicht sofort entfernt, sondern durch **VACUUM** aufgeräumt.
- Standard: Autovacuum kümmert sich darum. Manchmal Tuning nötig (`autovacuum_*`-Parameter).
### Isolation Levels
Standard-Level in PostgreSQL ist `READ COMMITTED`, `REPEATABLE READ` ist nicht exakt wie Oracle `SERIALIZABLE`. Es gibt zusätzlich ein echtes `SERIALIZABLE` via SSI (Serializable Snapshot Isolation).
```sql
SHOW default_transaction_isolation;
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ;
```
### DDL in Transaktionen
- PostgreSQL erlaubt DDL **innerhalb** von Transaktionen und kann diese zurückrollen:
```sql
BEGIN;
CREATE TABLE test (id int);
ROLLBACK; -- Tabelle existiert danach nicht
```
- Standard-Clients (z.B. `psql`) arbeiten mit Auto-Commit = ON, aber du kannst das Verhalten steuern.
**Lernpunkte:**
- VACUUM/Autovacuum verstehen: wann notwendig, wie überwachen, wie konfigurieren.
- Unterschiedliche Semantik von Isolation Levels im Detail prüfen (z.B. bei Portierung von Code, der sich auf Oracle-Sperrverhalten verlässt).
---
## 8. Indizes & Partitionierung
### Index-Typen
PostgreSQL bietet mehr verschiedene Index-Methoden:
- `btree` (Standard)
- `hash` (seltener)
- `GIN` (für Volltext, JSONB-Keys, Arrays)
- `GiST` (Geodaten, Range-Typen)
- `BRIN` (große append-only Tabellen, z.B. Logs)
Zusätzlich:
- **Expression Indexes**:
```sql
CREATE INDEX idx_lower_name ON kunde (lower(name));
```
- **Partial Indexes**:
```sql
CREATE INDEX idx_active_kunden ON kunde (id) WHERE aktiv = true;
```
### Partitionierung
Neuere PostgreSQL-Versionen haben native Partitionierung (Range, List, Hash). Unterschied zu Oracle:
- Implementierung anders, kein identisches Interface.
- Viele Operationen laufen „Partition-transparent“, aber es gibt noch Ecken (z.B. bestimmte DDL-Operationen).
```sql
CREATE TABLE messwerte (
id BIGINT GENERATED ALWAYS AS IDENTITY,
ts timestamptz NOT NULL,
wert numeric
) PARTITION BY RANGE (ts);
CREATE TABLE messwerte_2024 PARTITION OF messwerte
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
```
**Lernpunkte:**
- Eignung und Grenzen von GIN/GiST verstehen, wenn du JSONB oder Volltext planst.
- Partitionierungsstrategie neu durchdenken, statt 1:1 die Oracle-Logik zu kopieren.
---
## 9. Materialized Views
PostgreSQL hat Materialized Views, aber:
- Kein `ON COMMIT REFRESH`.
- Refresh ist explizit:
```sql
REFRESH MATERIALIZED VIEW my_mv;
```
- Optional mit `CONCURRENTLY` (mit Einschränkungen), um Downtime zu minimieren.
**Lernpunkt:** Wenn du in Oracle stark auf automatische Refresh-Mechanismen setzt, brauchst du in PostgreSQL einen eigenen Refresh-Workflow (z.B. Cron, Scheduler, Applikationslogik).
---
## 10. Rechte & Rollenmodell
Ähnlich, aber mit eigenen Begriffen/Details:
- Nur **Rollen** (kein getrenntes Konzept von „User“ und „Role“ wie in Oracle; ein User ist eine Login-fähige Rolle).
- Rechte auf Objekte (`GRANT SELECT ON table TO role;` etc.)
- Kein systemweites `PUBLIC SYNONYM`, aber es gibt das Schema `public` und das `PUBLIC`-Rolle/Privileges-Konzept.
```sql
CREATE ROLE app_user LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE mydb TO app_user;
GRANT USAGE ON SCHEMA app TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA app TO app_user;
```
**Lernpunkt:** Mapping deiner bisherigen Oracle-Rollen/Profiles auf PostgreSQL-Rollen und -Rechte.
---
## 11. Administration, Tools & Ökosystem
### Wichtige Tools
- `psql` (Kommandozeile, sehr mächtig)
- Admin-Tools: `pgAdmin`, `DBeaver`, `DataGrip` etc.
- Verbindungs-Pooler (wichtig, da PostgreSQL pro Verbindung einen Prozess startet):
- `pgbouncer`, `pgpool-II`
### Wichtige Admin-Konzepte
- **Konfiguration** über `postgresql.conf` und `ALTER SYSTEM`:
z.B. `shared_buffers`, `work_mem`, `maintenance_work_mem`, `max_connections`.
- **VACUUM/ANALYZE**:
- `VACUUM` räumt auf.
- `ANALYZE` aktualisiert Statistiken.
- **EXPLAIN/EXPLAIN ANALYZE**: zwingend für Performance-Tuning.
```sql
EXPLAIN ANALYZE
SELECT ...
FROM ...
WHERE ...;
```
- **Backup/Recovery**:
- Logische Backups: `pg_dump`, `pg_dumpall`.
- Physische Backups & PITR: Base-Backups + WAL-Archiving (oder Tools wie `pgBackRest`).
**Lernpunkte:**
- Verbindungspooling ist viel wichtiger als in Oracle.
- Autovacuum-Monitoring (z.B. via `pg_stat_*`-Views) und Basiskonfiguration.
---
## 12. Typische Stolpersteine beim Umstieg
1. **Fehlende Synonyme** → Lösung über `search_path`, Views, klare Schema-Strategie.
2. **Paketkonzept fehlt** → Namespacing neu denken.
3. **Materialized View Refresh** → eigene Scheduler-Logik.
4. **ROWNUM/`dual`** → an `LIMIT`/`OFFSET`, Window Functions, `SELECT 1;` gewöhnen.
5. **Datenbanklinks (`DBLINK`)** → Extension `dblink` oder `postgres_fdw` (Foreign Data Wrapper) verwenden.
6. **Autoincrement** → `IDENTITY`/`SERIAL` + `currval()/nextval()`-Verwendung lernen.
7. **Optimizer-Verhalten** → Statistiken, Parameter und Query-Pläne sind anders; alte „Index-Hints-Gewohnheiten“ greifen nicht 1:1.
---
## 13. Sinnvolle Lernreihenfolge
1. Basiskonzepte:
- Schemata + `search_path`
- Datentyp-Mapping (NUMBER, DATE, CLOB/BLOB → NUMERIC, TIMESTAMP, TEXT/BYTEA)
- Sequences & Identity
2. SQL-Dialekt:
- Funktionale Unterschiede (`DECODE`, `NVL`, `ROWNUM`, `dual`, Subqueries)
3. Server-seitige Logik:
- PL/pgSQL, Unterschiede zu PL/SQL, kein Package-Konzept
4. MVCC & Performance:
- VACUUM/Autovacuum, EXPLAIN ANALYZE, Index-Typen
5. Admin & Betrieb:
- Rollen, Backups, Konfiguration, Verbindungspooling
6. Spezielle Features:
- JSONB, Arrays, GIN-Indizes, Partitionierung, FDWs
Wenn du magst, kannst du mir ein paar typische Oracle-Features nennen, die du intensiv nutzt (z.B. bestimmte Partitionierungsarten, Advanced Queuing, bestimmte PL/SQL-Patterns). Dann kann ich dir eine gezielte „Mapping-Tabelle“ für genau diese Themen in PostgreSQL machen.