概要
PostgreSQLは、多くの異なるユースケースに対応できる強力なリレーショナルデータベースです。プロジェクトで使用する前に、PostgreSQLがどのように機能するか、他のリレーショナルデータベースとどう異なるか、データのモデル化と管理に役立つどのような機能があるかについて概要を把握しておくことをお勧めします。
このガイドでは、PostgreSQLのアーキテクチャと属性について説明し、データベースシステムがどのように機能するかを全体的に理解していただくことを目的としています。この概要を把握することで、アプリケーションアーキテクチャ、ユーザーが通常どのように対話するか、そしてスケーリングとセキュリティ機能を通じてデータの整合性と成長をどのようにサポートするかを理解するのに役立ちます。
PostgreSQLのクライアント/サーバーアーキテクチャ
多くのリレーショナルデータベースシステムと同様に、PostgreSQLの基本的なアーキテクチャはクライアント/サーバーモデルに従っています。
PostgreSQLのメインプログラムは、データ構造の定義、データの保存、およびクエリへの応答を担当するサービスとして実行されます。このデーモンはクライアントからの接続をリッスンし、クライアントは自身を認証した後、サーバーに命令を送信できます。サーバーは、成功、失敗、クエリ結果、またはその他の適切な情報を示すメッセージで応答します。
このアーキテクチャにより、PostgreSQLシステムはローカルまたはネットワーク経由で接続できるさまざまなクライアントに対応できます。マスターPostgreSQLプロセスは、受信するクライアント接続ごとに新しいプロセスをフォークします。このため、各フォークは単一のクライアント接続に専念するため、接続数、フォーク数、データベースセッション数は互いに整合します。
概念
- サーバー: クライアント/サーバーアーキテクチャにおいて、サーバーとは外部クライアントからの接続を受け入れて作業を実行するソフトウェアです。リクエストをリッスンし、適切な情報を処理し、関連する結果をユーザーに返します。
- クライアント: クライアント/サーバーアーキテクチャにおいて、クライアントとはユーザーがサーバーに接続し、通信するために操作するソフトウェアです。クライアントはユーザーからのリクエストをサーバーに中継し、関連する情報を返します。
- フォーク: フォークとは、実行中のプロセスのクローンであり、リソース使用量、特権レベルの制御、および新しい実行環境の作成によく使用されます。
- データベースセッション: データベースセッションとは、データベースサーバーとクライアント間の単一で継続的な接続です。セッションには独自のコンテキストがあり、セッションの存続期間中保持されるため、セッションごとに一定レベルのステートと構成が可能です。
PostgreSQLのデフォルトクライアント: psql
ユーザーはさまざまなクライアントを使用してPostgreSQLサーバーに接続できます。PostgreSQLディストリビューションの一部として実装されているデフォルトのコマンドラインクライアントはpsql
と呼ばれます。
psql
クライアントは、ローカルまたはリモートのデータベースに接続でき、クエリをバッチで処理することも、対話的に処理することもできます。自動化されたユースケースでは、認証情報は専用の認証ファイルに保存でき、クエリはファイルからクライアントによって読み取ることができます。
インタラクティブなpsql
セッションでは、認証後、ユーザーはPostgreSQLのコマンドプロンプトに移動します。そこから、SQLをクライアントに送信し、結果をターミナルウィンドウで表示するか、出力ファイルにパイプすることができます。
psql
クライアント内に実装されている一連のメタコマンドを介して、データベースを変更したり、PostgreSQL自体を管理したりすることもできます。メタコマンドは、データ構造やシステムに関する情報をクエリできる「\
」で始まる非SQLの利便性向上のためのショートカットです。
たとえば、\dt
メタコマンドを使用して利用可能なすべてのテーブルを一覧表示したり、\conninfo
メタコマンドを使用して現在の接続に関する情報を表示したりできます。psql
セッション中に\h
および\?
メタコマンドを使用すると、それぞれSQLまたはメタコマンドに関する情報を取得できます。
概念
- バッチ処理: バッチ処理とは、操作を一つずつではなく、まとめてグループで実行する戦略です。バッチ処理は、スクリプトやその他のプロセスが複合的なリクエストを送信できるため、通常、自動化されたワークフローのコンポーネントです。
- インタラクティブセッション: インタラクティブセッションとは、ユーザーがアドホックコマンドを使用してデータベースインターフェースと対話するデータベースセッションです。これは、ユーザーの介入なしに完全な一連の命令がサーバーに送信される非インタラクティブモードとは対照的です。
- メタコマンド:
psql
におけるメタコマンドとは、SQLステートメントとしてデータベースシステムではなく、psql
自体によってインターセプトおよび処理されるコマンドです。これらは主に、ユーザーが複雑なクエリを記憶することなく、データベースサーバー、接続、およびデータベースオブジェクトの構造に関する情報を取得できるようにする、利便性向上のためのものです。
Prisma Clientは、PostgreSQLコネクタを使用してPostgreSQLデータベースを操作するもう1つの強力な方法です。当社のPostgreSQL入門ガイドに従って試してみてください。
PostgreSQLのロールと権限による認証と認可
PostgreSQLは、システムに接続しているユーザーを検証し、実行を許可されているアクションを決定するために、ロールと権限を使用します。
PostgreSQLでは、ロールは特定の機能、権限、および「所有」エンティティのセットをグループ化したものです。「ユーザー」と「グループ」という別個の概念を持つ代わりに、PostgreSQLはこれらの両方のアイデアを表現するためにロールを使用します。ロールは現実世界の個人に対応することも、他のロールがメンバーとなることができる特定のアクセス権を持つグループとして機能することもできます。
このシステムは、アクセスレベルの編成において大きな柔軟性を提供します。認証方法はロールに応じて定義でき、特定のデータベースエンティティへの認可は特定のロールに付与できます。他のロールのメンバーであるロールは、それらのロールからアクセス権限を継承します。
PostgreSQLには、ユーザーログインと権限に関する初期状態での動作に影響を与えるいくつかの重要なデフォルト設定があります。新しいインストールでは、通常、ピア認証が構成されており、これによりユーザーは自身のオペレーティングシステムユーザーと一致するPostgreSQLロールに自動的に認証されます。基本的には、これはユーザー認証をオペレーティングシステムにオフロードします。一致するPostgreSQLロール名を持つオペレーティングシステムユーザーは、そのIDで信頼されていると見なされます。データベースで有用な作業を行うための認可は別途付与する必要があります。
概念
- ロール: PostgreSQLにおいて、ロールは個々のユーザーとユーザーグループの両方を置き換え、結合したものです。ユーザーはロールに対して認証を行うことで、その特権にアクセスできます。ロールは他のロールのメンバーとすることで、その特権を継承できます。
- ピア認証: ピア認証は、ほとんどのPostgreSQLインストールでデフォルトで構成されている認証メカニズムです。ピア認証により、ユーザーは追加の資格情報なしで、自身のオペレーティングシステムユーザー名と一致するPostgreSQLロールに対して認証を行うことができます。ピア認証は、システム管理者がデータベース管理者でもあるという仮定に基づいています。
- グラント(許可): PostgreSQLにおけるグラントとは、ロールに割り当てられた特定の操作を実行するための特権の宣言です。ロールは別のロールのメンバーシップを「付与」されることもあり、これにより親ロールのグラントをすべて継承することになります。
PostgreSQLのオブジェクト階層を理解する: データベース、スキーマ、テーブル
ほとんどの場合、PostgreSQLはデータベースオブジェクトに関して従来のリレーショナルデータベースの命名規則に従います。しかし、PostgreSQLが一般的な定義から逸脱する点の一つは、スキーマの定義方法です。
ほとんどのデータベースでは、「スキーマ」という言葉は、データベース内の一般的なデータベース構造やテーブル定義を指すために使用されます。たとえば、商品ID、説明、数量フィールドと関連する制約を持つproduct
テーブルを定義するSQLが、product
テーブルのスキーマと呼ばれるのを目にすることがあるでしょう。
しかし、PostgreSQLスキーマは、システム内で作成および管理できる特定のデータベースオブジェクトです。PostgreSQL内のオブジェクトの階層を理解することは、システムに慣れ、ドキュメントを読む際に混乱を避けるのに役立ちます。
PostgreSQLの主要な「グローバル」オブジェクトはデータベースクラスターであり、これはPostgreSQLサーバーによって管理されるデータベースの集合に与えられた名称です。データベースクラスターには、データベース、ロール、およびその他の「グローバル」エンティティが含まれます。
スキーマは、テーブル、関数、データ型、および演算子のコンテナとしてデータベース内に定義されます。オブジェクト名はスキーマ内で一意である必要がありますが、異なるスキーマで再利用できるため、ユーザーは名前の衝突なしにデータベースを共有できます。また、データベース内のオブジェクトをセグメント化および分離することで、オブジェクトのグループ化やサードパーティアプリケーションの管理にも役立ちます。
テーブルやその他のオブジェクトはスキーマ内に作成されます。デフォルトでは、代替スキーマが指定されていない場合、テーブルやその他のオブジェクトを定義する際に「public」というスキーマが使用されます。実際には、これによりスキーマを使用したセグメンテーションは任意のプラクティスとなります。多くの場合、PostgreSQLスキーマを使用することは役立ちますが、必要ない場合は無視できます。
概念
- データベースクラスター: PostgreSQLの用語では、データベースクラスターとは、単一のPostgreSQLサーバーによって管理されるデータベースと関連オブジェクトの集合です。データベースクラスターは、PostgreSQLサーバーによって管理される環境です。
- データベース: データベースとは、スキーマ、ロール、その他のオブジェクトを定義するデータベースクラスター内のオブジェクトです。ロールはデータベース内で定義されるため、データベースはユーザーが認証を行う対象のオブジェクトです。
- スキーマ: PostgreSQLにおいて、スキーマとはデータベース内の名前空間オブジェクトです。スキーマには、テーブル、データ型、関数、演算子が含まれます。オブジェクト名はスキーマ内で一意である必要がありますが、同じ名前が異なるスキーマに存在することもあります。
- テーブル: テーブルはPostgreSQLにおける主要なデータ定義構造です。テーブルは、入力されるデータの種類を制御するためのフィールドと制約を定義します。テーブルは、定義された構造内にレコードとしてデータを格納します。
Prisma Clientを操作する場合、PrismaスキーマのデータモデルはPostgreSQLのテーブルに相当します。
並行処理と分離制御
データベースの並行処理と分離制御は、複数のユーザーが同時に同じデータにアクセスしようとするインスタンスをシステムが管理するのに役立ちます。一貫性のない読み取り、競合する変更のコミット、および競合状態を避けるために、データベースがこれに対処する戦略を持つことが重要です。
PostgreSQLは、これらのシナリオを処理するために多版型同時実行制御 (MVCC)と呼ばれる戦略を使用します。MVCCは、関連データのスナップショットに対してSQLステートメントを実行することで機能します。このデータスナップショットはトランザクション分離を提供し、各トランザクションが独立して適用またはロールバックでき、一貫したデータセット上で操作されることを保証します。
この並行処理管理により、PostgreSQLはロッキング(1つのプロセスに対して操作の期間中データへの排他的アクセスを許可する技術)を回避できます。ロッキングは分離制御に役立つ一方で、同時アクセスを妨げ、クエリがロックの解放を待ってデータにアクセスするためパフォーマンスに影響を与えます。
PostgreSQLのMVCC実装により、読み取りおよび書き込みステートメントが互いをブロックすることがないため、パフォーマンスに大きな影響を与える可能性があります。複数のトランザクション分離レベルが利用可能であり、これは異なる種類の分離問題に対する許容度によって異なります。独自のシステムで並行処理のスコープをより細かく管理したい場合は、テーブルおよび行レベルのロッキングも利用できます。
概念
- トランザクション分離: トランザクション分離とは、トランザクションがアトミックかつ一貫していることを保証する特性です。これは、トランザクション内の操作がすべてデータに適用されるか、すべてロールバックされるかのいずれかであることを意味します。トランザクション分離はまた、トランザクションの期間中、外部プロセスがトランザクションが操作しているデータを変更できないことを保証します。
- MVCC: MVCC、すなわち多版型同時実行制御は、データの一貫性のあるスナップショットに対して操作を実行することにより、トランザクション分離を実現する戦略です。各トランザクションは、トランザクション内で使用するためにデータの独自のコピーを受け取ります。
- ロッキング: データベース、テーブル、または行のロッキングとは、トランザクションの期間中、特定のデータ範囲への排他的アクセスをプロセスに与えることにより、不正確な読み取りを防ぎ、競合する書き込みを回避する戦略です。ロッキングは効果的ですが、同時アクセスが許可されないため、パフォーマンスに深刻な影響を与えます。
レプリケーション、ロードバランシング、高可用性
PostgreSQLは、ワークロードを複数のサーバーに分散させたり、プライマリサーバーに問題が発生した場合にセカンダリサーバーに切り替えたりするためのさまざまなソリューションを提供しています。
ロードバランシングは、複数のデータベースサーバーでデータを複製し、それらの間でリクエストを交互に処理することで、並行して実行できる作業量を増やす戦略です。同様に、高可用性は、プライマリデータベースサーバーに問題が発生した場合にセカンダリデータベースサーバーがその役割を引き継ぎ、データが利用できない時間を短縮する戦略です。これら両方の戦略は、先行書き込みログ (WAL)とレプリケーションの組み合わせを通じてPostgreSQLで実現可能です。
先行書き込みログ(WAL)は、すべての変更を実際にデータベースに適用する前にログファイルに書き込むことで、データの整合性を保証するのに使用される手法です。トランザクション中に障害が発生した場合、PostgreSQLはログを確認することで、データベースにどの操作が正確に適用されたかを特定できます。これにより、システムが意図された変更を正確に把握しているため、部分的に適用されたトランザクションをロールバックすることができます。
WALは、レプリケーションとの関係から、ロードバランシングと高可用性にとって重要です。レプリケーションは、2つ以上のデータベースサーバー間でデータとすべてのデータベース操作をミラーリングするプロセスです。これは、サーバー間でデータを複製する手段を提供することにより、ロードバランシングと高可用性の両方を実装する主要な方法です。
PostgreSQLは、粒度、データ損失保護、パフォーマンス、複雑さに関してトレードオフを伴う多くの異なる種類のレプリケーションをサポートできます。レプリケーションアーキテクチャは、単一のスタンバイサーバーにデータをコピーするような簡単なものから、さまざまな程度の遅延を伴って複数のホストを介してレプリケーションを中継する複雑なものまであります。これらの選択肢により、パフォーマンス、スケーリング、およびデータ可用性のニーズに合わせて環境を柔軟に構成できます。
概念
- 先行書き込みログ (WAL): 先行書き込みログ、またはWALとは、サーバー障害時のデータ損失を防ぐための戦略であり、意図されたデータベース操作をデータベース上で実行する前に、永続的なログに書き込みます。WALにより、データベースは部分的に適用された操作をロールバックすることで障害から回復できます。これは、システム内のデータが一貫した状態にあることを保証するのに役立ちます。
- レプリケーション: レプリケーションとは、データとデータ操作をあるサーバーから別のサーバーにコピーするプロセスです。これにより、個別のサーバーが同期されたデータセットを維持できます。さまざまなレベルの可用性、障害許容度、パフォーマンス、および複雑さのバランスを取るために、さまざまな種類のレプリケーションが利用可能です。
- プライマリサーバー: データをレプリケートする際、プライマリサーバー(一部の文脈ではマスターサーバーと呼ばれる)とは、書き込みクエリを受け入れ、データの初期セットと操作を維持する「メイン」サーバーの呼称です。
- セカンダリサーバー: データをレプリケートする際、セカンダリサーバー(一部の文脈ではスタンバイサーバーと呼ばれる)とは、実行される各操作をレプリケートすることにより、そのデータをプライマリサーバーに同期させるサーバーです。
まとめ
PostgreSQLは、非常に強力なデータベースであり、多くの異なるタスクで優れた性能を発揮できる柔軟性を持っています。クライアント/サーバーモデル、ユーザー管理システム、オブジェクト階層、および並行処理とレプリケーション機能は、PostgreSQLがこれほど優れた機能を発揮する上での基本的な要素です。PostgreSQL開発者が行った基礎的な設計上の選択肢を理解することは、システムで生産性を高めるための道のりを楽にするでしょう。