346 lines
11 KiB
Markdown
Executable File
346 lines
11 KiB
Markdown
Executable File
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. |