1 pontos por GN⁺ 2024-02-18 | 1 comentários | Compartilhar no WhatsApp

Minhas notas sobre o design do schema Postgres do GitLab

  • Ao analisar o schema Postgres do GitLab, quis comparar com o schema que eu mesmo projeto e aprender boas práticas na definição de schemas do GitLab.
  • O GitLab é uma plataforma DevOps de código aberto, uma alternativa ao GitHub e pode ser autohospedado.

Usar os tipos corretos de chave primária

  • Em um banco de dados pequeno isso pode não parecer importante, mas conforme ele cresce, a chave primária impacta o espaço de armazenamento, a velocidade de escrita e a velocidade de leitura.
  • O GitLab usa bigserial como tipo de chave primária em 380 das 573 tabelas, serial4 em 170 e nas 23 restantes usa chaves primárias compostas.

Uso de IDs internos e externos

  • É uma boa prática não expor a chave primária ao mundo externo.
  • O GitLab usa tanto IDs internos (id) quanto IDs externos (iid) em tabelas como issues, ci_pipelines, deployments e epics.

Uso de text e restrições CHECK para campos de texto

  • O schema do GitLab usa tanto character varying(n) quanto text, mas usa mais frequentemente o tipo text.
  • O tipo text não tem restrição de comprimento, então ele define restrições de tamanho com CHECK.

Convenções de nomenclatura

  • Todas as tabelas usam nomes no plural e usam prefixos de módulo para fornecer namespace.
  • Os nomes de tabela e coluna seguem o padrão snake_case.

Uso de fuso horário em timestamps

  • O GitLab usa tanto timestamp with timezone quanto timestamp without timezone.
  • Para operações do sistema usa timestamp without timezone, enquanto para ações de usuário usa timestamp with timezone.

Restrições de chave estrangeira

  • O GitLab usa restrições de chave estrangeira na maioria das tabelas, mas não as utiliza em algumas tabelas, como audit_events, abuse_reports, web_hooks_logs e spam_logs.

Particionamento de tabelas grandes

  • O GitLab particiona tabelas grandes que podem crescer para melhorar o desempenho de consultas.

Como dar suporte a casos de uso de busca com LIKE usando trigramas e gin_trgm_ops

  • O GitLab usa índices GIN (Generalized Inverted Index) para realizar buscas de forma eficiente.

Uso de jsonb

  • O schema do GitLab usa o tipo de dado jsonb em várias tabelas.

Dicas extras

  • Em tabelas editáveis, ele usa campos de auditoria como updated_at, enquanto em tabelas de log imutáveis esse campo não é usado.
  • Enums são armazenados como smallint em vez de character varying para economizar espaço.

Opinião do GN⁺:

  • O design do schema do GitLab oferece insights sobre design de banco de dados e traz lições importantes sobre otimização de schema para sistemas em larga escala.
  • Como o GitLab é open source, essas decisões de design de schema oferecem exemplos práticos que outros desenvolvedores podem aplicar em seus próprios projetos.
  • O que podemos aprender com o schema do GitLab é que escolhas de tipo de dado, estratégia de indexação, particionamento e uso de restrições de chave estrangeira precisam ser feitas com cuidado porque impactam significativamente desempenho e manutenção de banco de dados.

1 comentários

 
GN⁺ 2024-02-18
Comentário do Hacker News
  • Não expor chaves primárias externamente é uma prática geralmente recomendada. Isso é especialmente importante ao usar identificadores inteiros ou bigint de auto incremento sequencial, pois eles podem ser previstos.

    • É destacado que não expor chaves primárias é uma boa prática. Em especial, isso é ainda mais importante quando os identificadores inteiros sequenciais podem ser previstos.
  • Em 2020, por exemplo, o GitHub tinha 128 milhões de repositórios públicos. Assumindo 20 issues por repositório, a faixa serial seria ultrapassada. Além disso, mudar o tipo de tabela custa caro.

    • A partir do número de repositórios públicos do GitHub e da estimativa de issues por repositório, é indicado que a faixa de serial pode ser excedida, e o custo de alterar o tipo da tabela é citado.
  • O argumento de que o tamanho de armazenamento de uma coluna UUID não é convincente. Em uma tabela com 5 outras colunas, não há grande diferença entre 128 bits e 64 bits.

    • Em vez de se preocupar com o tamanho de armazenamento de UUID, argumenta-se que o problema de desempenho é mais importante. O UUIDv4 é totalmente aleatório e não é ideal para desempenho de índice, sendo citado que o UUIDv7 pode ser uma solução melhor.
  • A afirmação de que chaves estrangeiras têm alto custo é frequentemente repetida, mas é uma alegação quase sem validação. Usar o banco de dados bem é mais desafiador e exige conhecimento e experimentação do que reimplementar, e geralmente oferece melhores resultados.

    • Questiona-se a alegação de que chaves estrangeiras são caras, enfatizando que aproveitar o banco de dados corretamente é importante.
  • Fiquei curioso para saber se alguém escreveu sobre ou notou a diferença de desempenho entre GitLab e GitHub.

    • Expressa interesse em uma diferença de desempenho entre GitLab e GitHub, sentindo que o tempo de carregamento de páginas no GitLab é visivelmente mais lento do que no GitHub.
  • Quis entender o motivo do acréscimo do "I" nas variáveis de CI CI_PIPELINE_IID e CI_MERGE_REQUEST_IID. Eu havia suspeitado de uma escolha de banco de dados; este texto confirma isso.

    • Manifesta curiosidade sobre o propósito do I extra nas variáveis de CI e entende que isso confirma uma escolha relacionada ao banco de dados.
  • Este texto foi muito útil. Gostaria de saber onde encontrar outro texto parecido.

    • O texto foi considerado muito útil, e há interesse em encontrar materiais semelhantes.
  • Sou o único que pensa que o design e o desenvolvimento de esquema são antiquados?

    • Diz que considera o design e o dev de esquema ultrapassados, especialmente ao migrar dados, sente risco de perda de dados. Questiona por que o banco de dados/ORM não cuida automaticamente de IDs externos e internos.
  • 1 gyeong equivale a 10.000 trilhões.

    • Destaca a realidade de ter que escolher entre inteiro de 32 bits e inteiro de 64 bits, mencionando a necessidade de um inteiro de 5 bytes para suportar cardinalidade em torno de 1 trilhão.
  • Usar o tipo nativo UUID v4 do Postgres aumenta o tamanho da tabela em 25% e reduz a taxa de inserção em 25% em comparação ao bigserial.

    • Mostra interesse sobre a diferença de desempenho entre UUIDv4 e bigserial, e pede explicação do porquê o UUIDv4 tem desempenho pior.