# Gitlab의 Postgres 스키마 디자인에 대한 나의 노트 (2022)

> Clean Markdown view of GeekNews topic #13419. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=13419](https://news.hada.io/topic?id=13419)
- GeekNews Markdown: [https://news.hada.io/topic/13419.md](https://news.hada.io/topic/13419.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-02-18T18:35:52+09:00
- Updated: 2024-02-18T18:35:52+09:00
- Original source: [shekhargulati.com](https://shekhargulati.com/2022/07/08/my-notes-on-gitlabs-postgres-schema-design/)
- Points: 1
- Comments: 1

## Topic Body

### 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의 스키마에서 배울 수 있는 점은, 데이터 유형 선택, 인덱싱 전략, 파티셔닝, 외래 키 제약 조건의 사용 등 데이터베이스 성능과 유지 관리에 중요한 영향을 미치는 요소들을 신중하게 고려해야 한다는 것임.

## Comments



### Comment 23137

- Author: neo
- Created: 2024-02-18T18:35:52+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=39413972) 
- > 기본 키를 외부에 노출하지 않는 것은 일반적으로 좋은 관행임. 특히 정수형이나 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가 왜 더 나쁜 성능을 보이는지에 대한 설명을 요청함.
