1P by neo 10달전 | favorite | 댓글 1개

GitLab Postgres 스키마 디자인에 대한 나의 노트

  • GitLab의 Postgres 스키마를 살펴봄으로써, 자신이 설계하는 스키마와 비교하고, GitLab의 스키마 정의에서 모범 사례를 배우고자 함.
  • GitLab은 오픈 소스 DevOps 플랫폼으로, GitHub의 대안이며 자체 호스팅이 가능함.

올바른 기본 키 유형 사용하기

  • 데이터베이스가 작을 때는 눈에 띄지 않지만, 성장함에 따라 기본 키가 저장 공간, 쓰기 속도, 읽기 속도에 영향을 미침.
  • GitLab은 573개의 테이블 중 380개는 bigserial 기본 키 유형을, 170개는 serial4를 사용하고, 나머지 23개는 복합 기본 키를 사용함.

내부 및 외부 ID의 사용

  • 기본 키를 외부 세계에 노출하지 않는 것이 좋은 관행임.
  • GitLab은 issues, ci_pipelines, deployments, epics 등의 테이블에서 내부 ID(id)와 외부 ID(iid)를 모두 사용함.

text 문자 유형과 검사 제약 조건 사용하기

  • GitLab 스키마는 character varying(n)text를 모두 사용하지만, text 유형을 더 자주 사용함.
  • text 유형은 길이 제약을 가지고 있지 않으며, CHECK를 사용하여 길이 제약을 정의함.

명명 규칙

  • 모든 테이블은 복수형을 사용하며, 모듈 이름 접두사를 사용하여 네임스페이스를 제공함.
  • 테이블과 열 이름은 snake_case 규칙을 따름.

타임스탬프의 시간대 사용

  • GitLab은 timestamp with timezonetimestamp without timezone을 모두 사용함.
  • 시스템 작업에는 timestamp without timezone을, 사용자 작업에는 timestamp with timezone을 사용함.

외래 키 제약 조건

  • GitLab은 대부분의 테이블에서 외래 키 제약 조건을 사용하지만, audit_events, abuse_reports, web_hooks_logs, spam_logs와 같은 몇몇 테이블에서는 사용하지 않음.

큰 테이블의 파티셔닝

  • GitLab은 쿼리 성능을 향상시키기 위해 크기가 커질 수 있는 테이블을 파티셔닝함.

Trigrams과 gin_trgm_ops를 사용하여 LIKE 검색 사용 사례 지원하기

  • GitLab은 GIN(Generalized Inverted Index) 인덱스를 사용하여 효율적인 검색을 수행함.

jsonb의 사용

  • GitLab 스키마는 여러 테이블에서 jsonb 데이터 유형을 사용함.

기타 팁

  • 수정 가능한 테이블에는 updated_at과 같은 감사 필드를 사용하고, 수정할 수 없는 로그 테이블에는 사용하지 않음.
  • Enums는 character varying 대신 smallint로 저장되어 공간을 절약함.

GN⁺의 의견:

  • GitLab의 스키마 디자인은 데이터베이스 설계에 대한 통찰력을 제공하며, 특히 대규모 시스템을 위한 스키마 최적화에 대한 중요한 교훈을 담고 있음.
  • GitLab이 오픈 소스이기 때문에, 이러한 스키마 설계 결정들은 다른 개발자들이 자신의 프로젝트에 적용할 수 있는 실질적인 예시를 제공함.
  • GitLab의 스키마에서 배울 수 있는 점은, 데이터 유형 선택, 인덱싱 전략, 파티셔닝, 외래 키 제약 조건의 사용 등 데이터베이스 성능과 유지 관리에 중요한 영향을 미치는 요소들을 신중하게 고려해야 한다는 것임.
Hacker News 의견
  • 기본 키를 외부에 노출하지 않는 것은 일반적으로 좋은 관행임. 특히 정수형이나 bigint 타입의 순차적 자동 증가 식별자를 사용할 때 중요함, 이들은 추측 가능하기 때문임.

    • 기본 키를 외부에 노출하지 않는 것이 좋은 관행이라는 의견이 제시됨. 특히 순차적으로 증가하는 정수형 식별자는 추측 가능하므로 더욱 중요함.
  • 예를 들어, Github는 2020년에 1억 2천 8백만 개의 공개 저장소를 가지고 있었음. 저장소 당 20개의 이슈가 있다고 가정하면 시리얼 범위를 넘어섬. 또한 테이블의 타입을 변경하는 것은 비용이 많이 듬.

    • Github의 공개 저장소 수와 이슈의 예상 수를 들어 시리얼 범위를 넘어설 수 있음을 지적하며, 테이블 타입 변경의 비용 문제를 언급함.
  • UUID 컬럼의 저장 크기에 대한 논점은 설득력이 없음. 테이블에 다른 컬럼이 5개 있을 때 128비트 대 64비트는 큰 차이가 없음.

    • UUID 컬럼의 저장 크기에 대한 우려보다는 성능 문제가 더 중요하다고 주장함. UUIDv4는 완전히 무작위이며 인덱스 성능에 이상적이지 않음을 지적하고, UUIDv7이 더 나은 해결책이 될 수 있음을 언급함.
  • 외래 키는 비용이 많이 든다는 것은 자주 반복되지만 거의 검증되지 않은 주장임. 데이터베이스를 활용하는 것이 재구현하는 것보다 지식과 실험이 필요하며, 종종 더 나은 결과를 가져옴.

    • 외래 키의 비용에 대한 일반적인 주장에 의문을 제기하며, 데이터베이스를 적절히 활용하는 것이 중요함을 강조함.
  • Gitlab과 GitHub의 성능 차이에 대해 쓴 글이나 주목한 사람이 있는지 궁금함.

    • Gitlab과 GitHub의 성능 차이에 대한 관심을 표현하며, Gitlab의 페이지 로딩 시간이 GitHub에 비해 현저히 느리다고 느낌.
  • CI 변수 CI_PIPELINE_IIDCI_MERGE_REQUEST_IID에서 "I"가 추가된 목적이 궁금했음. 데이터베이스 관련 선택으로 추정했지만, 이 글이 그것을 확인해줌.

    • CI 변수에서 볼 수 있는 추가적인 "I"의 목적에 대해 궁금증을 표하며, 이것이 데이터베이스 관련 선택임을 이해함.
  • 이 글이 매우 유용했음. 이와 비슷한 다른 글을 어디에서 찾을 수 있는지 궁금함.

    • 글이 유용했다고 느끼며, 비슷한 내용의 다른 자료를 찾고 싶어함.
  • 일반적으로 스키마 설계와 개발이 구시대에 머물러 있다고 생각하는 사람이 나뿐인가?

    • 스키마 설계와 개발이 시대에 뒤떨어져 있다고 느끼며, 특히 마이그레이션을 할 때 데이터 손실의 위험을 느낌. 데이터베이스/ORM이 외부 ID와 내부 ID를 자동으로 처리해주지 않는 점에 대해 의문을 제기함.
  • 1경은 1000000000조와 같음.

    • 32비트 정수와 64비트 정수 사이에서 선택해야 하는 현실을 지적하며, 약 1조의 카디널리티를 지원할 수 있는 5바이트 정수 타입의 필요성을 언급함.
  • Postgres의 네이티브 UUID v4 타입을 사용할 때 테이블 크기가 25% 증가하고, bigserial 대비 삽입 속도가 25%로 떨어짐.

    • UUIDv4와 bigserial의 성능 차이에 대해 궁금해하며, UUIDv4가 왜 더 나쁜 성능을 보이는지에 대한 설명을 요청함.