1 ポイント 投稿者 GN⁺ 2024-02-18 | 1件のコメント | WhatsAppで共有

GitLabのPostgresスキーマ設計に関する私のメモ

  • GitLabのPostgresスキーマを調べることで、独自に設計するスキーマと比較し、GitLabのスキーマ定義からベストプラクティスを学び取ることを目的とした。
  • GitLabはオープンソースのDevOpsプラットフォームで、GitHubの代替として、自社でホスト可能。

適切な主キー型の選択

  • データベースが小さいうちは目立たないが、成長するにつれて主キーはストレージ容量、書き込み速度、読み取り速度に影響を与える。
  • GitLabでは、573のテーブルのうち380がbigserialの主キー型、170がserial4を使用し、残り23が複合主キーを使用している。

内部IDと外部IDの利用

  • 主キーを外部世界に公開しないことはよいプラクティスである。
  • GitLabは、issuesci_pipelinesdeploymentsepicsなどのテーブルで、内部ID(id)と外部ID(iid)の両方を使用している。

text型とCHECK制約の使用

  • GitLabのスキーマはcharacter varying(n)textの両方を使用しているが、text型の方が頻繁に使われている。
  • text型は長さの制約を持たず、CHECKを使って長さ制約を定義する。

命名規則

  • すべてのテーブルに複数形を使用し、モジュール名のプレフィックスでネームスペースを提供する。
  • テーブルと列名はsnake_case規則に従う。

タイムスタンプのタイムゾーン設定

  • GitLabはtimestamp with timezonetimestamp without timezoneの両方を使用している。
  • システム操作にはtimestamp without timezoneを、ユーザー操作にはtimestamp with timezoneを使用している。

外部キー制約

  • GitLabはほとんどのテーブルで外部キー制約を使用しているが、audit_eventsabuse_reportsweb_hooks_logsspam_logsなどの一部のテーブルでは使用していない。

大きなテーブルのパーティショニング

  • GitLabはクエリのパフォーマンス向上のため、サイズが拡大しうるテーブルをパーティション分割する。

Trigramとgin_trgm_opsを使用したLIKE検索ユースケースのサポート

  • GitLabはGIN(Generalized Inverted Index)インデックスを使用して効率的な検索を実行している。

jsonbの使用

  • GitLabのスキーマでは複数のテーブルでjsonbデータ型を使用している。

その他のヒント

  • 更新可能なテーブルにはupdated_atのような監査フィールドを使用し、更新不可能なログテーブルでは使用しない。
  • Enumsはcharacter varyingの代わりにsmallintで保存され、スペースを節約している。

GN⁺の意見:

  • GitLabのスキーマ設計はデータベース設計に対する洞察を提供し、特に大規模システム向けのスキーマ最適化に関する重要な教訓を含んでいる。
  • GitLabがオープンソースであるため、このようなスキーマ設計の意思決定は、他の開発者が自分のプロジェクトに適用できる実践的な例を提供する。
  • GitLabのスキーマから学べることは、データ型の選択、インデックス戦略、パーティショニング、外部キー制約の使用など、データベースの性能と保守性に大きな影響を与える要素を慎重に考慮することが必要だという点だ。

1件のコメント

 
GN⁺ 2024-02-18
Hacker Newsの意見
  • 主キーを外部に公開しないことは一般的に良い慣行です。特に整数型やbigint型の順次増分される自動増加識別子を使う場合は重要で、これらは推測可能だからです。

    • 主キーを外部に公開しないことが良い慣行であるという意見が示されています。特にシーケンシャルな整数型識別子は予測可能なため、より重要です。
  • たとえばGitHubは2020年に1億2,800万件の公開リポジトリを持っていました。リポジトリあたり20件のIssueがあると仮定すると、シリアルの範囲を超えてしまいます。また、テーブル型の変更コストは高くなります。

    • GitHubの公開リポジトリ数と1リポジトリあたりのIssue想定数を挙げて、シリアルの上限を超える可能性を指摘し、テーブル型変更のコスト問題に触れています。
  • 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京は10億兆と同等です。

    • 32ビット整数と64ビット整数の間で選択を迫られる現実を指摘し、約1兆のカーディナリティをサポートできる5バイト整数型が必要であることに言及しています。
  • PostgresのネイティブUUID v4型を使用するとテーブルサイズが25%増加し、bigserialに比べて挿入速度が25%低下します。

    • UUIDv4とbigserialの性能差に関心を寄せ、UUIDv4がなぜより悪い性能を示すのか説明を求めています。