GN⁺: Gitlab의 Postgres 스키마 디자인에 대한 나의 노트 (2022)
(shekhargulati.com)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 timezone
과timestamp 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_IID
와CI_MERGE_REQUEST_IID
에서 "I"가 추가된 목적이 궁금했음. 데이터베이스 관련 선택으로 추정했지만, 이 글이 그것을 확인해줌.- CI 변수에서 볼 수 있는 추가적인 "I"의 목적에 대해 궁금증을 표하며, 이것이 데이터베이스 관련 선택임을 이해함.
-
이 글이 매우 유용했음. 이와 비슷한 다른 글을 어디에서 찾을 수 있는지 궁금함.
- 글이 유용했다고 느끼며, 비슷한 내용의 다른 자료를 찾고 싶어함.
-
일반적으로 스키마 설계와 개발이 구시대에 머물러 있다고 생각하는 사람이 나뿐인가?
- 스키마 설계와 개발이 시대에 뒤떨어져 있다고 느끼며, 특히 마이그레이션을 할 때 데이터 손실의 위험을 느낌. 데이터베이스/ORM이 외부 ID와 내부 ID를 자동으로 처리해주지 않는 점에 대해 의문을 제기함.
-
1경은 1000000000조와 같음.
- 32비트 정수와 64비트 정수 사이에서 선택해야 하는 현실을 지적하며, 약 1조의 카디널리티를 지원할 수 있는 5바이트 정수 타입의 필요성을 언급함.
-
Postgres의 네이티브 UUID v4 타입을 사용할 때 테이블 크기가 25% 증가하고, bigserial 대비 삽입 속도가 25%로 떨어짐.
- UUIDv4와 bigserial의 성능 차이에 대해 궁금해하며, UUIDv4가 왜 더 나쁜 성능을 보이는지에 대한 설명을 요청함.