1 points par GN⁺ 2024-02-18 | 1 commentaires | Partager sur WhatsApp

Mes notes sur la conception du schéma Postgres de GitLab

  • En étudiant le schéma Postgres de GitLab, je voulais le comparer au schéma que je conçois et apprendre de bonnes pratiques à partir des définitions de schéma de GitLab.
  • GitLab est une plateforme DevOps open source, alternative à GitHub et pouvant être auto-hébergée.

Utiliser le bon type de clé primaire

  • Quand la base de données est petite, on ne le remarque pas, mais à mesure qu’elle grandit, la clé primaire impacte l’espace de stockage, la vitesse d’écriture et la vitesse de lecture.
  • GitLab utilise bigserial comme type de clé primaire pour 380 des 573 tables, serial4 pour 170, et des clés primaires composites pour les 23 restantes.

Utiliser des IDs internes et externes

  • Il est recommandé de ne pas exposer la clé primaire au monde extérieur.
  • GitLab utilise à la fois l’ID interne (id) et l’ID externe (iid) dans des tables comme issues, ci_pipelines, deployments et epics.

Utiliser le type texte text avec des contraintes CHECK

  • Le schéma de GitLab utilise à la fois character varying(n) et text, mais emploie plus souvent le type text.
  • Le type text n’impose pas de contrainte de longueur, et GitLab utilise CHECK pour définir la contrainte de longueur.

Conventions de nommage

  • Toutes les tables sont au pluriel et utilisent un préfixe de nom de module pour fournir un espace de noms.
  • Les noms des tables et des colonnes suivent la convention snake_case.

Gestion des fuseaux horaires des timestamps

  • GitLab utilise à la fois timestamp with timezone et timestamp without timezone.
  • Les opérations système utilisent timestamp without timezone, tandis que les actions utilisateur utilisent timestamp with timezone.

Contraintes de clé étrangère

  • GitLab applique des contraintes de clé étrangère sur la plupart des tables, mais pas sur certaines, comme audit_events, abuse_reports, web_hooks_logs et spam_logs.

Partitionnement des grandes tables

  • GitLab partitionne les tables qui peuvent devenir volumineuses afin d’améliorer les performances des requêtes.

Prise en charge des cas d’usage de recherche LIKE avec les trigrammes et gin_trgm_ops

  • GitLab utilise des index GIN (Generalized Inverted Index) pour effectuer des recherches efficaces.

Utiliser jsonb

  • Le schéma de GitLab utilise le type de données jsonb dans plusieurs tables.

Autres conseils

  • Les tables modifiables utilisent des champs d’audit comme updated_at, tandis que les tables de logs immuables ne l’utilisent pas.
  • Les enums sont stockées en smallint au lieu de character varying pour économiser de l’espace.

GN⁺ :

  • La conception du schéma de GitLab apporte des enseignements utiles pour la conception de base de données, notamment des leçons clés sur l’optimisation de schéma pour les systèmes à grande échelle.
  • Comme GitLab est open source, ces décisions de conception de schéma fournissent des exemples pratiques que d’autres développeurs peuvent appliquer à leurs propres projets.
  • Les points importants à retenir du schéma de GitLab sont qu’il faut considérer attentivement des éléments qui affectent fortement les performances et la maintenance de la base de données, comme le choix des types de données, la stratégie d’indexation, le partitionnement et l’usage des contraintes de clés étrangères.

1 commentaires

 
GN⁺ 2024-02-18
Commentaires Hacker News
  • Il est généralement préférable de ne pas exposer la clé primaire à l’extérieur. C’est particulièrement important avec des identifiants auto-incrémentés de type integer ou bigint, car ils sont prévisibles.

    • L’idée qu’il ne faut pas exposer la clé primaire à l’extérieur est présentée comme une bonne pratique. C’est d’autant plus important avec des identifiants entiers qui augmentent de manière séquentielle, car ils peuvent être devinés.
  • Par exemple, GitHub comptait 128 millions de dépôts publics en 2020. En supposant 20 issues par dépôt, cela dépasse la plage de serial. De plus, modifier le type d’une table est coûteux.

    • En s’appuyant sur le nombre de dépôts publics de GitHub et le nombre d’issues attendu, il souligne qu’il est possible de dépasser la plage de serial et mentionne le coût élevé d’un changement de type de table.
  • L’argument sur la taille de stockage d’une colonne UUID n’est pas convaincant. Quand il y a déjà cinq autres colonnes dans une table, la différence entre 128 bits et 64 bits n’est pas importante.

    • Il soutient qu’il faut surtout se préoccuper des performances, plus que de la taille de stockage d’une colonne UUID. Il souligne que UUIDv4 est totalement aléatoire et donc peu adapté aux performances des index, et indique que UUIDv7 peut être une meilleure solution.
  • Affirmer que les clés étrangères sont coûteuses est une idée souvent répétée mais rarement vérifiée. Bien utiliser une base de données demande davantage de compétences et d’expérimentations que de réimplémenter, et apporte souvent de meilleurs résultats.

    • Il remet en cause l’affirmation classique selon laquelle les clés étrangères seraient coûteuses, en soulignant l’importance d’exploiter correctement la base de données.
  • Je me demande si quelqu’un a écrit quelque chose sur la différence de performance entre GitLab et GitHub.

    • Il exprime son intérêt pour la différence de performance entre GitLab et GitHub, et dit que le chargement des pages de GitLab lui semble nettement plus lent que celui de GitHub.
  • Je m’étais demandé pourquoi un « I » avait été ajouté aux variables CI CI_PIPELINE_IID et CI_MERGE_REQUEST_IID. J’avais supposé qu’il s’agissait d’un choix lié à la base de données, et cet article le confirme.

    • Il fait part de sa curiosité sur l’objectif du I supplémentaire visible dans les variables CI et comprend qu’il s’agit d’un choix lié à la base de données.
  • Cet article a été très utile. Je me demande où trouver d’autres articles du même type.

    • Il indique qu’il a trouvé cet article très utile et qu’il souhaite trouver d’autres ressources de ce type.
  • Suis-je le seul à penser que la conception de schéma et le développement sont un peu archaïques ?

    • Il exprime le sentiment que la conception et le développement de schémas sont désuets, évoquant notamment le risque de perte de données lors des migrations et s’interrogeant sur le fait que la base de données/ORM ne gère pas automatiquement les IDs externe et interne.
  • 1경 correspond à 10^21.

    • Il souligne la nécessité de choisir entre les types entier 32 bits et 64 bits, en mentionnant le besoin d’un type entier sur 5 octets pouvant gérer une cardinalité d’environ 1 000 000 000 000.
  • Lorsqu’on utilise le type natif UUID v4 de Postgres, la taille de la table augmente de 25 % et la vitesse d’insertion tombe à 25 % par rapport à bigserial.

    • Il s’interroge sur la différence de performance entre UUIDv4 et bigserial, et demande pourquoi UUIDv4 donne de moins bonnes performances.