1 Punkte von GN⁺ 2024-02-18 | 1 Kommentare | Auf WhatsApp teilen

Meine Notizen zum GitLab-Postgres-Schema-Design

  • Indem ich mir das Postgres-Schema von GitLab anschaue, kann ich es mit meinem eigenen Schema vergleichen und Best Practices aus GitLabs Schemadefinition ableiten.
  • GitLab ist eine Open-Source-DevOps-Plattform, eine Alternative zu GitHub, die selbst gehostet werden kann.

Richtige Verwendung von Primärschlüsseltypen

  • Wenn eine Datenbank klein ist, fällt das kaum auf, mit dem Wachstum wirken sich Primärschlüssel jedoch auf Speicherplatz, Schreibgeschwindigkeit und Lesegeschwindigkeit aus.
  • Von 573 Tabellen verwendet GitLab bigserial als Primärschlüsseltyp in 380 Tabellen, serial4 in 170, und die übrigen 23 nutzen zusammengesetzte Primärschlüssel.

Verwendung interner und externer IDs

  • Es ist eine gute Praxis, Primärschlüssel nicht nach außen hin offenzulegen.
  • GitLab verwendet in Tabellen wie issues, ci_pipelines, deployments und epics sowohl interne IDs (id) als auch externe IDs (iid).

Verwendung von text-Datentypen und CHECK-Einschränkungen

  • Das GitLab-Schema verwendet sowohl character varying(n) als auch text, wobei es text häufiger nutzt.
  • Der Datentyp text hat keine Längenbeschränkung; GitLab definiert die Längenbeschränkung stattdessen mit CHECK.

Namenskonventionen

  • Alle Tabellen sind im Plural benannt und nutzen Modulnamenpräfixe, um Namespaces bereitzustellen.
  • Tabellen- und Spaltennamen folgen der snake_case-Konvention.

Zeitzonennutzung bei Timestamps

  • GitLab verwendet sowohl timestamp with timezone als auch timestamp without timezone.
  • Für Systemvorgänge wird timestamp without timezone verwendet, für Benutzeraktivitäten timestamp with timezone.

Fremdschlüssel-Constraints

  • GitLab nutzt Fremdschlüssel-Constraints in den meisten Tabellen, in einigen wie audit_events, abuse_reports, web_hooks_logs und spam_logs jedoch nicht.

Partitionierung großer Tabellen

  • GitLab partitioniert Tabellen, die im Laufe der Zeit groß werden können, um die Abfrageleistung zu verbessern.

Unterstützung von LIKE-Suchfällen mit Trigrammen und gin_trgm_ops

  • GitLab nutzt GIN(Generalized Inverted Index)-Indizes, um eine effiziente Suche bereitzustellen.

Einsatz von jsonb

  • Das GitLab-Schema verwendet den Datentyp jsonb in mehreren Tabellen.

Weitere Tipps

  • Änderbare Tabellen haben Audit-Felder wie updated_at, unveränderliche Log-Tabellen dagegen nicht.
  • Enums werden als smallint statt character varying gespeichert, um Platz zu sparen.

GN⁺-Meinung:

  • Das GitLab-Schema-Design liefert Einblicke in die Datenbankgestaltung und beinhaltet wichtige Lehren, insbesondere zur Schema-Optimierung für Großsysteme.
  • Da GitLab Open Source ist, liefern solche Schema-Entscheidungen praktische Beispiele, die andere Entwickler in ihren eigenen Projekten übernehmen können.
  • Was man aus dem GitLab-Schema lernen kann, ist, dass Datentypauswahl, Indexierungsstrategie, Partitionierung und der Einsatz von Fremdschlüssel-Constraints zu Aspekten beitragen, die die Datenbankleistung und Wartbarkeit maßgeblich beeinflussen.

1 Kommentare

 
GN⁺ 2024-02-18
Hacker News Kommentare
  • Es gilt als gute Praxis, Primärschlüssel nicht öffentlich preiszugeben, insbesondere bei automatisch inkrementierenden Integer- oder bigint-IDs, da diese vorhersagbar sind.

    • Eine gute Praxis ist, Primärschlüssel nicht nach außen offenzulegen. Besonders bei fortlaufenden Ganzzahl-IDs ist das wichtig, weil sie vorhersagbar sind.
  • GitHub hatte 2020 rund 128 Millionen öffentliche Repositories. Geht man von 20 Issues pro Repository aus, wird der Serial-Bereich überschritten. Außerdem sind Änderungen am Tabellentyp teuer.

    • Er verweist auf die Anzahl öffentlicher GitHub-Repositories und die geschätzte Issue-Nummer und stellt fest, dass dadurch der Serial-Bereich überschritten werden kann; außerdem weist er auf die Kosten eines Tabellentypp-Wechsels hin.
  • Das Argument, dass die Speichergröße einer UUID-Spalte entscheidend sei, ist nicht überzeugend; bei fünf weiteren Spalten in einer Tabelle ist der Unterschied zwischen 128 und 64 Bit kaum relevant.

    • Er betont, dass Performance-Fragen wichtiger sind als reine Speichergröße. Außerdem weist er darauf hin, dass UUIDv4 vollständig zufällig ist und für die Index-Performance nicht ideal, und nennt UUIDv7 als mögliche bessere Lösung.
  • Die Behauptung, dass Fremdschlüssel teuer seien, wird oft wiederholt, ist aber kaum belegt. Die Datenbank korrekt zu nutzen erfordert statt Re-Implementierung mehr Wissen und Experimentierfreude und führt häufig zu besseren Ergebnissen.

    • Er stellt den verbreiteten Vorwurf der hohen Kosten von Fremdschlüsseln infrage und betont, wie wichtig es ist, die Datenbank sinnvoll zu nutzen.
  • Ich würde gern wissen, ob jemand einen Beitrag zu den Performance-Unterschieden zwischen GitLab und GitHub gesehen hat.

    • Er äußert sein Interesse an den Performance-Unterschieden zwischen GitLab und GitHub und findet GitLab im Seitenaufbau deutlich langsamer als GitHub.
  • Mich hat interessiert, warum in den CI-Variablen CI_PIPELINE_IID und CI_MERGE_REQUEST_IID ein zusätzliches I steckt. Ich habe angenommen, es sei eine Datenbank-Entscheidung, und dieser Beitrag bestätigt das.

    • Er fragt nach dem Zweck des zusätzlichen I in diesen CI-Variablen und versteht es dann als eine datenbankbezogene Designentscheidung.
  • Dieser Beitrag war sehr hilfreich. Ich frage mich, wo man ähnliche Beiträge finden kann.

    • Er sagt, der Beitrag sei hilfreich gewesen, und möchte wissen, wo sich ähnliche Inhalte finden lassen.
  • Bin ich der Einzige, der den Eindruck hat, dass Schema-Design und -Entwicklung insgesamt rückständig sind?

    • Er fühlt, dass Schema-Design und -Entwicklung generell altmodisch sind; bei Migrationen befürchtet er Datenverlust. Er fragt sich, warum die Datenbank/ORM externe und interne IDs nicht automatisch behandelt.
  • 1 Kyeong entspricht 1.000.000.000 Trillionen.

    • Er weist auf die reale Entscheidung zwischen 32- und 64-Bit-Integers hin und spricht den Bedarf an einem 5-Byte-Integertyp mit etwa 1 Billion Kardinalität an.
  • Bei Verwendung des nativen Postgres UUIDv4-Typs wächst die Tabellengröße um 25 % und die Einfügegeschwindigkeit ist im Vergleich zu bigserial auf 25 % gesunken.

    • Er ist neugierig auf den Performance-Unterschied zwischen UUIDv4 und bigserial und fragt nach einer Erklärung, warum UUIDv4 schlechtere Performance zeigt.