概要
PostgreSQL は、さまざまなユースケースに対応できる強力なリレーショナルデータベースです。プロジェクトで使用する前に、PostgreSQLがどのように動作するのか、他のリレーショナルデータベースとどのように異なるのか、データをモデル化および管理するのに役立つどのような機能が利用できるのかを概観することをお勧めします。
このガイドでは、PostgreSQLのアーキテクチャと属性について説明し、データベースシステムがどのように機能するかについての一般的な理解を提供します。この概要は、アプリケーションアーキテクチャ、ユーザーが通常どのように対話するか、およびスケーリングと安全機能を通じてデータ整合性と成長をどのようにサポートするかを理解するのに役立ちます。
PostgreSQLのクライアント/サーバーアーキテクチャ
多くのリレーショナルデータベースシステムと同様に、PostgreSQLの基本的なアーキテクチャはクライアントサーバーモデルに従っています。
メインのPostgreSQLプログラムは、データ構造の定義、データの保存、およびクエリへの応答を担当するサービスとして実行されます。このデーモンは、クライアントからの接続をリッスンし、クライアントは自身を認証してから、サーバーに指示を送信できます。サーバーは、成功、失敗、クエリ結果、またはその他の適切な情報を示すメッセージで応答します。
このアーキテクチャにより、PostgreSQLシステムは、ローカルまたはネットワーク経由で接続できる多くの異なるクライアントにサービスを提供できます。マスターPostgreSQLプロセスは、受信したクライアント接続ごとに新しいプロセスをフォークします。このため、各フォークは単一のクライアント接続専用であるため、接続数、フォーク数、およびデータベースセッション数は互いに一致します。
概念
- サーバー:クライアントサーバーアーキテクチャでは、サーバーは外部クライアントからの接続を受け入れて作業を実行するソフトウェアです。リクエストをリッスンし、適切な情報を処理し、関連する結果をユーザーに返します。
- クライアント:クライアントサーバーアーキテクチャでは、クライアントはユーザーがサーバーに接続して通信するために操作するソフトウェアです。クライアントは、ユーザーからのリクエストをサーバーに中継し、関連情報を返送します。
- フォーク:フォークは、実行中のプロセスのクローンであり、リソースの使用状況、特権レベルの制御、および新しい実行環境の作成を支援するためによく使用されます。
- データベースセッション:データベースセッションは、データベースサーバーとクライアント間の単一の継続的な接続です。セッションには、セッションのライフサイクル全体にわたって持続する独自のコンテキストがあり、セッションごとに一定レベルの状態と構成を可能にします。
PostgreSQLのデフォルトクライアント:psql
ユーザーは、さまざまなクライアントを使用してPostgreSQLサーバーに接続できます。PostgreSQLディストリビューションの一部として実装されているデフォルトのコマンドラインクライアントは、psql
と呼ばれます。
psql
クライアントは、ローカルまたはリモートデータベースに接続し、クエリをバッチ処理またはインタラクティブに処理できます。自動化されたユースケースの場合、認証資格情報は専用の認証ファイルに保存でき、クエリはファイルからクライアントによって読み取ることができます。
インタラクティブなpsql
セッションでは、認証時にユーザーをPostgreSQLコマンドプロンプトにドロップします。そこから、SQLをクライアントに送信し、結果をターミナルウィンドウで表示するか、出力ファイルにパイプできます。
また、psql
クライアント内で実装された一連のメタコマンドを使用して、データベースを変更し、PostgreSQL自体を管理することもできます。メタコマンドは、データ構造とシステムに関する情報をクエリできるようにする、「\
」で始まる非SQLの「QOL」ショートカットです。
たとえば、\dt
メタコマンドを使用して、使用可能なすべてのテーブルを一覧表示したり、\conninfo
メタコマンドを使用して、現在の接続に関する情報を表示したりできます。psql
セッション中に\h
および\?
メタコマンドを使用して、それぞれSQLまたはメタコマンドに関する情報を取得できます。
概念
- バッチ処理:バッチ処理は、操作の束を1つずつではなくグループで実行する戦略です。バッチ処理は通常、スクリプトやその他のプロセスが複合リクエストを送信できるようにするため、自動化されたワークフローのコンポーネントです。
- インタラクティブセッション:インタラクティブセッションは、ユーザーがアドホックコマンドを使用してデータベースインターフェイスと対話するデータベースセッションです。これは、ユーザーの介入なしに完全な命令セットがサーバーに送信される非インタラクティブモードとは対照的です。
- メタコマンド:
psql
では、メタコマンドは、SQLステートメントとしてデータベースシステムによって処理されるのではなく、psql
自体によってインターセプトおよび処理されるコマンドです。これらは主に、ユーザーが複雑なクエリを覚えなくても、データベースサーバー、接続、およびデータベースオブジェクトの構造に関する情報を取得できるようにするQOL改善です。
Prisma Clientは、PostgreSQLコネクタを使用してPostgreSQLデータベースを操作するもう1つの強力な方法です。PostgreSQLスタートガイドに従って試すことができます。
PostgreSQLのロールと権限による認証と認可
PostgreSQLは、ロールと権限を使用して、システムに接続しているユーザーを検証し、実行できるアクションを決定します。
PostgreSQLでは、ロールは特定の機能、権限、「所有」エンティティのグループ化です。PostgreSQLは、「ユーザー」と「グループ」の個別の概念を持つ代わりに、ロールを使用してこれらの両方のアイデアを表します。ロールは、現実世界の個人に対応することも、他のロールがメンバーになることができる特定のアクセス権を持つグループとして機能することもできます。
このシステムは、アクセスレベルを編成する上で非常に柔軟性を提供します。認証方法はロールに従って定義でき、特定のデータベースエンティティへの認可は特定のロールに付与できます。他のロールのメンバーであるロールは、それらのロールからアクセス権限を継承します。
PostgreSQLには、ユーザーログインと権限に関するデフォルトの動作に影響を与える重要なデフォルトがいくつかあります。新しいインストールは通常、ピア認証で構成されており、これにより、ユーザーはオペレーティングシステムユーザーと一致するPostgreSQLロールに対して自動的に認証できます。基本的に、これはユーザー認証をオペレーティングシステムにオフロードします。一致するPostgreSQLロール名を持つオペレーティングシステムユーザーは、そのIDで信頼されていると見なされます。データベースで有用な作業を行うための認可は、別途付与する必要があります。
概念
- ロール:PostgreSQLでは、ロールは個々のユーザーとユーザーグループの両方の代替および組み合わせです。ユーザーはロールに対して認証して、その権限へのアクセス権を取得できます。ロールは、別のロールのメンバーにして、その権限を継承させることができます。
- ピア認証:ピア認証は、ほとんどのPostgreSQLインストールでデフォルトで構成されているデフォルトの認証メカニズムです。ピア認証により、ユーザーは追加の資格情報なしで、オペレーティングシステムのユーザー名と一致するPostgreSQLロールに対して認証できます。ピア認証は、システム管理者がデータベース管理者でもあるという前提に基づいています。
- 権限付与:PostgreSQLの権限付与は、ロールに割り当てられた特定の操作を実行する権限の宣言です。ロールは、別のロールへのメンバーシップを「付与」することもでき、それにより、親ロールの権限付与を継承します。
PostgreSQLオブジェクト階層の理解:データベース、スキーマ、テーブル
ほとんどの場合、PostgreSQLはデータベースオブジェクトに関して従来のリレーショナルデータベースの命名規則に従っています。ただし、PostgreSQLが一般的な定義から逸脱する点の1つは、スキーマを定義する方法です。
ほとんどのデータベースでは、「スキーマ」という単語を使用して、データベース内の一般的なデータベース構造またはテーブル定義を指します。たとえば、製品ID、説明、およびカウントフィールドと、product
テーブルのスキーマと呼ばれる関連する制約を持つproduct
テーブルを定義するSQLまたはSQLが表示される場合があります。
ただし、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は、ワークロードを複数のサーバーに分散したり、プライマリサーバーに問題が発生した場合にセカンダリサーバーに切り替えたりするためのさまざまなソリューションを提供します。
ロードバランシングは、複数のデータベースサーバーでデータを複製し、それらの間でリクエストを交互に実行して、同時に実行できる作業量を増やす戦略です。同様に、高可用性は、最初のデータベースサーバーに問題が発生した場合に、セカンダリデータベースサーバーが最初のデータベースサーバーの責任を引き継ぐことを可能にする戦略であり、データが利用できなくなる時間を短縮します。これらの戦略はどちらも、Write-Ahead Logging(WAL)とレプリケーションの組み合わせを通じてPostgreSQLで可能です。
Write-Ahead Loggingは、データベースに実際に適用する前に、すべての変更をログファイルに書き込むことにより、データ整合性を保証するために使用される手法です。トランザクション中に障害が発生した場合、PostgreSQLはログをチェックすることにより、データベースに適用された操作を正確に判断できます。部分的に適用されたトランザクションは、システムが意図された変更を正確に把握しているため、ロールバックできます。
WALは、レプリケーションとの関係があるため、ロードバランシングと高可用性にとって重要です。レプリケーションは、2つ以上のデータベースサーバー間でデータとすべてのデータベース操作をミラーリングするプロセスです。これは、サーバー間でデータを複製する手段を提供することにより、ロードバランシングと高可用性の両方を実装する主要な方法です。
PostgreSQLは、多くの異なるタイプのレプリケーションをサポートできます。それぞれに、粒度、データ損失保護、パフォーマンス、および複雑さに関するトレードオフがあります。レプリケーションアーキテクチャは、データを単一のスタンバイサーバーにコピーするなど、単純なものにすることも、さまざまな程度の遅延を持つ複数のホストを介してレプリケーションをリレーするアーキテクチャを備えた複雑なものにすることもできます。これらの選択肢により、パフォーマンス、スケーリング、およびデータ可用性のニーズに合わせて環境を柔軟に構成できます。
概念
- Write-Ahead Logging:Write-Ahead Logging(WAL)は、データベース操作をデータベースで実行する前に、意図したデータベース操作を永続ログに書き込むことにより、サーバーの障害時のデータ損失を防ぐための戦略です。WALを使用すると、データベースは部分的に適用された操作をロールバックすることにより、障害から回復できます。これにより、システム内のデータが一貫性のある状態になることが保証されます。
- レプリケーション:レプリケーションは、データとデータ操作をあるサーバーから別のサーバーにコピーするプロセスです。これにより、個別のサーバーがデータの同期されたセットを維持できます。可用性、耐障害性、パフォーマンス、および複雑さのさまざまなレベルのバランスを取るために、さまざまなタイプのレプリケーションを利用できます。
- プライマリサーバー:データをレプリケートする場合、プライマリサーバー(一部のコンテキストではマスターサーバーと呼ばれる)は、書き込みクエリを受け入れ、データの初期セットと操作を維持できる「メイン」サーバーの指定です。
- セカンダリサーバー:データをレプリケートする場合、セカンダリサーバー(一部のコンテキストではスタンバイサーバーと呼ばれる)は、実行される各操作をレプリケートすることにより、データをプライマリサーバーに同期するサーバーです。
結論
PostgreSQLは、非常に強力なデータベースであり、さまざまなタスクで優れたパフォーマンスを発揮できるほど柔軟性があります。クライアントサーバーモデル、ユーザー管理システム、オブジェクト階層、同時実行およびレプリケーション機能は、PostgreSQLが適切に機能するための基本的な部分です。PostgreSQL開発者が行った基本的な設計上の選択肢を理解することで、システムを生産的に使用するための道のりが楽になります。