Logo GH

PostgreSQL: Best Practices und Indexierung

(Abschnitt: Technologie und Infrastruktur)

Kurze Zusammenfassung

PostgreSQL ist der „Kern der Wahrheit“ für Geld, KYC und rechtlich relevante Einträge in iGaming. Es gibt ACID-Garantien, leistungsstarke SQL und Erweiterbarkeit. Um den Spitzen von Turnieren und PSP-Webhooks standzuhalten, sind kritisch: ein kompetentes Schema, Indizes, Partitionierung, Auto-Vakuum, WAL-Tuning und Beobachtbarkeit. Im Folgenden finden Sie den Builder für Praktiken und Vorlagen.

1) Architektur und SLO

Die Rolle von PostgreSQL: Leader to Write + Replikate to Read; für Hot Screens - Cache/Projektionen (Redis/materialisierte Ansichten).
SLO Beispiele: p99 'INSERT/UPDATE' wallet ≤ 25-40 ms; p99 Lesen der Balance ≤ 10-15 ms; Lag Repliken ≤ 2-5 s; Verfügbarkeit ≥ 99. 9%.
Read-After-Write-Richtlinie: Benutzerdefinierte Bildschirme nach einer Transaktion, die vom Leader gelesen werden oder auf einen Replikationsfehler warten.

2) Schaltungsdesign

Normalisierung des Geldkerns (Geldbörsen, Ledger) + Denormalisierung zum Lesen (CQRS/Projektionen).
Strenge Einschränkungen: 'NOT NULL', 'CHECK', 'UNIQUE', FK mit gezieltem 'ON DELETE/UPDATE' (RESTRICT/SET NULL/NO ACTION).
Schema-Versionierung: Auf/Ab-Migrationen, Feature-Flags; Vermeiden Sie brechende Umbenennungen in heißen Zeiten.
Kennungen: 'BIGINT' + Sequenzen (oder ULID/UUIDv7 für die Verteilung). Für Hot Inserts - Sequenzen in einem separaten Tablespace/WAL-Volume.

3) Indexierung: Was, wo und wie

3. 1 B-Baum (Ausfall)

Wann: genaue Entsprechungen, Bereiche, Sortierung, 'JOIN' nach FK.
Die Muster lauten: „WHERE player_id =?“, „ORDER BY created_at DESC LIMIT 100“.

Praxen:
  • Mehrspaltige Indizes - Erfüllen Sie die Reihenfolge der Bedingungen.
  • Covering: `INCLUDE (...)` для index-only scan.
  • Separater Index unter 'ORDER BY... DESC 'auf „Bänder“.
sql
CREATE INDEX idx_tx_player_created_desc
ON tx (player_id, created_at DESC) INCLUDE (amount_cents, status);

3. 2 GIN (JSONB, Arrays, Volltext)

Wann: JSONB-Suche nach Schlüssel/Pfad, Tag-Arrays, FTS.
Optionen: 'gin _ trgm _ ops' für Trigramme,' jsonb _ path _ ops'/' jsonb _ ops'.
Praxis: Schränken Sie die Suchfelder streng ein und denken Sie an die Kardinalität.

sql
CREATE INDEX idx_profile_jsonb_gin
ON player_profile USING GIN (data jsonb_path_ops);

-- Search by email/name with typos
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX idx_player_trgm ON player USING GIN (email gin_trgm_ops);

3. 3 GiST (Geo/Bereiche/Signaturen)

Wann: Geolokalisierung (IP-Geo, Radien), Intervalle, nearest-neighbor.
Weniger verwendet im Geldkern, nützlich für Geobeschränkungen/verantwortungsvolles Spielen.

3. 4 BRIN (große „Appendix“ -Tabellen in der Zeit)

Wann: Milliarden von Zeilen, natürliche zeitliche Korrelation (Wett-/Ereignisprotokolle).
Vorteile: geringe Größe, billiger Service.
Nachteile: Grobe Selektivität → mit Partitionierung kombiniert werden.

sql
CREATE INDEX idx_bets_brin ON bets USING BRIN (created_at) WITH (pages_per_range = 64);

3. 5 Hash

Selten benötigt: Gleichheit einer Spalte in Abwesenheit von Bereichen; häufiger reicht B-Tree.

3. 6 Partielle und Ausdrücke

Partieller Index: beschleunigt heiße Untermengen (aktiv, 'status =' pending').
Ausdruck Index: Vorwegnahme des Schlüssels ('lower (email)','(data->> 'psp _ tx')').

sql
CREATE INDEX idx_withdraw_pending ON withdrawals (player_id)
WHERE status = 'pending';

CREATE INDEX idx_tx_psp_tx ON tx ((data->>'psp_tx'));

3. 7 Anti-Pattern-Indizes

„Index für alles“: Ein Überschuss an Indizes hemmt die Erfassung und VACUUM.
Doppelte Indizes (gleiche Menge von Spalten/Reihenfolge).
Index pro Spalte mit sehr geringer Kardinalität (z.B. 'status' mit 2 Werten) - partiell machen.

4) Partitionierung

Warum: Reduzieren Sie Bloat, beschleunigen Sie VACUUM/Scans, erleichtern Sie Retention/Archiv.
Schemata: RANGE nach Datum (Tag/Woche) für Wettprotokolle; HASH durch 'player _ id' für große benutzerdefinierte Tabellen; kombiniert.
Rotationspraxis: Erstellen Sie im Voraus zukünftige Parteien, 'ATTACH PARTITION', Archiv der alten - 'DETACH' + Umzug.

sql
CREATE TABLE bets (
bet_id BIGINT PRIMARY KEY,
player_id BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
amount_cents BIGINT NOT NULL
) PARTITION BY RANGE (created_at);

CREATE TABLE bets_2025_11_05 PARTITION OF bets
FOR VALUES FROM ('2025-11-05') TO ('2025-11-06');

5) Einfügungen/Updates mit minimaler Fragmentierung

HOT-Updates: Halten Sie' fillfactor'(z. B. 90) auf heißen Tabellen für freien Speicherplatz auf der Seite.
TOAST: große JSONB/Texte - achten Sie auf die Kompaktheit; Speichern Sie sperrige Felder in einer separaten Tabelle.
UPSERT: Verwenden Sie' ON CONFLICT... DO UPDATE ™ mit idempotenter Logik.

sql
INSERT INTO wallet (player_id, balance_cents, updated_at)
VALUES ($1, $2, now())
ON CONFLICT (player_id) DO UPDATE
SET balance_cents = wallet. balance_cents + EXCLUDED. balance_cents,
updated_at = now();

6) Transaktionen, Sperren und Wettbewerb

Isolationsstufen: 'READ COMMITTED' für die meisten Pfade; 'REPEATABLE READ '/' SERIALIZABLE' Punkt (Berichte, Offline-Batches). Halten Sie sie nicht lange.
Arten von Sperren: Row-Level (Pessimismus' FOR UPDATE'), Table-Level (DDL), Advisory-Sperren für verteilte Mutexe.
Deadlocks: kurze Transaktionen, einheitliche Reihenfolge der Aktualisierung von Entitäten, Timeouts ('lock _ timeout', 'statement _ timeout').
Aufgabenwarteschlangen: 'SKIP LOCKED' für einen verteilten Workpool.

sql
-- batch processor removes work without racing
SELECT id FROM jobs
WHERE status='pending'
FOR UPDATE SKIP LOCKED
LIMIT 100;

7) Auto-Vakuum, Statistik und Bloat

VACUUM/ANALYZE: Halten Sie aktuelle Statistiken ('default _ statistics _ target'), tunen Sie AV auf heißen Tabellen (Auslöseschwelle unten).
Achten Sie auf wraparound (Alter (txid) <2 Milliarden), 'vacuum _ freeze _ min _ age'.
bloat-control: regelmäßige reindex/CLUSTER auf schweren Indizes außerhalb der Peaks; Partitionierung verringert das Ausmaß des Problems.

Beispielrichtlinie (Tabelleneinstellungen):
sql
ALTER TABLE tx SET (
autovacuum_vacuum_scale_factor = 0. 05,
autovacuum_analyze_scale_factor = 0. 02,
autovacuum_vacuum_cost_limit = 4000
);

8) Gedächtnis, Checkpoints und WAL

Gedächtnis

'shared _ buffers': 20-25% RAM (profilabhängig).
'work _ mem': nach Operation! Passen Sie sich konservativ an (z. B. 8-64MB) und erhöhen Sie punktgenau für Berichtsrollen.
'maintenance _ work _ mem': große Indizes/Wiederherstellung (512MB-2GB nach Aufgabe).

WAL und Checkpoints

NVMe für WAL, separates Volume; 'wal _ compression = on'.
'checkpoint _ timeout' 10-15 min, 'max _ wal _ size' unter dem Umfang der Änderungen, 'checkpoint _ completion _ target ≈ 0. 9`.
Für Einfügungsspitzen gibt es Batch-Einfügungen und Gruppen-Commits.

9) Replikation und Fehlertoleranz

Lead-Repliken: synchron zum nächsten (Semi-Sync) für RPO≈0 -30c; asynchron für Lesungen/Analysen.
Promotion und Fencing: Patroni/Replik-Manager; „Doppelspitze“ abzuschaffen.
Hot standby: 'hot _ standby _ feedback' vorsichtig (Wachstum bloat), besser - zähmen lange Transaktionen auf Repliken.

10) Backups und PITRs

Vollständige + inkrementelle Sicherung, Offsite-Kopien; 'archive _ command' für WAL.
PITR: Überprüfen Sie die Wiederherstellung bis zum Zeitpunkt an den Ständen; Regeln Sie RPO/RTO (Geldbörsen - Minuten, Protokolle - Dutzende von Minuten).
DR (Spieltag) Übungen: regelmäßige Überprüfung der Erholung.

11) JSONB und das Modell der „flexiblen Schaltung“

JSONB - Ideal für selten lesbare/variable Attribute (KYC-Metadaten, PSP-Parameter).
Die Pflichtfelder in den relationalen Spalten streng validieren; JSONB ist für den „Schwanz“ der Nuancen.
Indexierung: Punkt-zu-Punkt-GIN nach verwendeten Pfaden; Vermeiden Sie „einen riesigen GIN für alles“.

sql
-- partial GIN index only for documents with the desired key
CREATE INDEX idx_kyc_docnum ON kyc USING GIN ((data->'doc'->'number'))
WHERE data? 'doc';

12) Volltext und fuzzy-Suche

Eingebauter FTS: 'tsvector' + GIN; Tippfehler: „pg _ trgm“.
Für eine schwere Suche nach Protokollen/Spielen - in die Suchmaschine (ES/OpenSearch) mitnehmen und in PG einen Link/Metadaten speichern.

13) Beobachtbarkeit und Profilierung

pg_stat_statements: Top langsame/häufige Anfragen, Normalisierung.
EXPLAIN (ANALYZE, BUFFERS): Lesen Sie die Pläne, suchen Sie nach seq scan auf den heißen Pfaden.
Metriken: TPS, p95/p99, Checkpoints, 'replication _ lag', Deadlocks, Bloat, AV-Loops, Cache-Hit ≥ 95%.
Alertas: Anstieg der Verzögerungen, „idle in transaction“, unerwartete seq scan, WAL-Sturm.

14) Verbindungspool und vorbereitete Anfragen

Puller (PgBouncer) im 'Transaction' -Modus für Web-Verkehr; 'Session' - für lange Cursor/Backoffice.
Vorbereitete Aussagen/Parametrisierung → weniger Parsing, stabile Pläne.
Begrenzen Sie die maximale Anzahl von Beckends ('max _ connections' niedrig; Pool übernimmt das Ventil).

15) Sicherheit und Compliance

TLS im Transit, Festplattenverschlüsselung, KMS/Fremdschlüssel.
RBAC: Mindestrechte, Rollenaufteilung Lesen/Schreiben/Admin.
RLS (Row-Level Security) für Multi-Tenant-Szenarien.
PII: Maskierung/Pseudonymisierung, Speicherdauer.
Audit: 'pgaudit '/Audit-Trigger auf kritischen Tabellen (Wallet/Ledger).

16) Typische Vorlagen für iGaming

16. 1 Wallet und Ledger (strikte Konsistenz)

Индексы: `wallet(player_id PK)`, `ledger(player_id, ts DESC)` + `INCLUDE (delta_cents, reason)`.
Die Transaktion aktualisiert den Saldo und schreibt an ledger; Semi-Sync-Replikation; Cache nur als Projektion.

16. 2 Wettverlauf (hoher TPS, Lesen nach Spieler/Zeit)

Partitionierung nach Tag/Woche, BRIN nach Zeit + B-Tree'(player_id, created_at DESC)'.
Retention über „DETACH PARTITION“ → Archivierung in OLAP.

16. 3 PSP Webhooks (Burstami, Retrays)

Warteschlange der „rohen“ Ereignisse (append-only), Partitionen nach Zeit, Teilindex nach 'status =' pending'.
Idempotenz durch 'idempotency _ key '/' psp _ tx' (UNIQUE).

17) Checkliste Umsetzung

1. Fix SLO und Read-After-Write-Richtlinie.
2. Entwerfen Sie Schlüsselindizes für reale Abfragen (Anforderungsprofil).
3. Aktivieren Sie die Partitionierung, wenn Retention/Append-Muster vorhanden sind.
4. Konfigurieren Sie AV/ANALYZE auf heißen Tabellen, achten Sie auf bloat/wraparound.
5. Tune Speicher, WAL und Checkpoints für Spitzenfenster.
6. Stellen Sie den Verbindungspool und 'pg _ stat _ statements'; Übernehmen Sie die Alerts.
7. Replikation + DR + PITR - erforderlich; Führen Sie Übungen durch.
8. Beschränken Sie JSONB und GIN nur auf die erforderlichen Pfade; Verwenden Sie partielle Indizes.
9. Minimieren Sie die Transaktionsdauer, verwenden Sie' SKIP LOCKED 'für Workqueues.
10. Audit/PII/Verschlüsselung/Rollenmodell - vor dem Start der Zahlungen.

18) Antipatterns

Ein „universeller“ Index für alles und keine Anforderungsanalyse.
Lange „hängende“ Transaktionen ('idle in transaction') → bloat Blockaden/Wachstum.
Verlassen Sie sich auf Repliken für Read-After-Write ohne Berücksichtigung der Verzögerung.
Speichern Sie alles in JSONB „nur für den Fall“ und indizieren Sie das gesamte Dokument mit einer GIN.
Null VACUUM/ANALYZE-Kontrolle und keine Überwachung von Verzögerungen/Checkpoints.
Massenmigrationen/DDLs in Spitzenzeiten.

19) Nützliche Snippets

Anforderungsplan und Puffer

sql
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT amount_cents
FROM ledger
WHERE player_id = $1
ORDER BY ts DESC
LIMIT 100;

Profilierung von „schweren“ Anfragen

sql
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;

Rotation von Parteien (Idee)

sql
-- create a party for tomorrow
CREATE TABLE bets_2025_11_06 PARTITION OF bets
FOR VALUES FROM ('2025-11-06') TO ('2025-11-07');

Ergebnisse

PostgreSQL ist in der Lage, „Geld und Wahrheit“ auf der iGaming-Plattform zu ziehen, wenn die Last linear steigt - wenn Indizes, Partitionen, Auto-Vakuum, WAL/Speicher, Replik/DR und Beobachtbarkeit diszipliniert sind. Beginnen Sie mit einem Anforderungsprofil und SLOs, erstellen Sie Indizes für reale Muster, isolieren Sie heiße Tabellen, aktivieren Sie strenge Betriebshygiene - und die Basis wird Turniere und Spitzenzahlungen vorhersehbar halten.

Contact

Kontakt aufnehmen

Kontaktieren Sie uns bei Fragen oder Support.Wir helfen Ihnen jederzeit gerne!

Integration starten

Email ist erforderlich. Telegram oder WhatsApp – optional.

Ihr Name optional
Email optional
Betreff optional
Nachricht optional
Telegram optional
@
Wenn Sie Telegram angeben – antworten wir zusätzlich dort.
WhatsApp optional
Format: +Ländercode und Nummer (z. B. +49XXXXXXXXX).

Mit dem Klicken des Buttons stimmen Sie der Datenverarbeitung zu.