4

現在バックエンドとして PostgreSQL のみをサポートし、独自のユーザー管理を持つ Web アプリケーションがあります。データベースへの接続は、Postgres 認証メカニズムを使用する汎用ユーザー アカウントを使用して行われます。このアプリケーションは、できればトリガーとストアド プロシージャのみに基づいて、作成および変更されたデータの監査ログを取得する必要があります。パフォーマンス上の理由から、すべてが非同期で Web アプリケーションから独立して動作するとよいでしょう。

主な問題が 1 つあります。Web アプリケーションのどのユーザーが何らかの変更を行ったかデータを作成したかを知りたいのですが、一般的なアカウントを使用して Postgres に接続するため、通常、ストアド プロシージャではこの情報をすぐに利用することはできません。私が避けたいのは、Web アプリケーションでストアド プロシージャを呼び出し、そのようにユーザー ID を提供することです。これは、Web アプリケーションの多くの場所に関連する呼び出しを追加することを意味するためです。それに加えて、Web アプリケーションを使用せずにデータベースを使用してデータ モデルを直接更新します。つまり、いずれにしてもトリガーが必要になります。

現在、Web アプリケーションは、すべてのリクエストで開始され、最後にコミットされたトランザクションで動作しています。したがって、作成または変更されたデータのトリガーによって実行されるストアドプロシージャで使用できるリクエストの現在のユーザーIDを常に取得するすべてのリクエストで、トランザクション内に一時テーブルを作成することを考えました。

私が知らないいくつかのことは、実行されたストアド プロシージャがデータベースの現在のトランザクションにアクセスできるかどうか、したがって一時テーブルから現在のユーザー ID を取得できるかどうかです。テーブルは、トリガーが作成された変更済みデータの一部ではありません。最悪の場合、各リクエストが 1 つの整数のみを格納する一時テーブルを作成すると、パフォーマンスにどのような影響がありますか? トリガーが一時テーブルにアクセスできる場合、作業が完了したかエラーが発生したため、リクエストはいつでも終了する可能性があります。ストアド プロシージャがユーザー ID を読み取ろうとしているときにコミットまたは元に戻されるトランザクション内でのみ終了する一時テーブルにアクセスできるトリガーにどのように影響しますか?

ユーザーIDを、トリガーがアクセスできるトランザクションの一意の識別子にマップできる他の方法はありますか? 一時テーブルのほかに、現在のトランザクションとは関係なく、すべてのリクエストの開始時にユーザー ID をトランザクション ID にマップする通常のテーブルを作成できます。トリガーがトリガーの実行を担当するトランザクション ID を取得する場合、ストアド プロシージャはトランザクション ID を使用して、トランザクションを使用したユーザー ID を検索できます。

何かご意見は?ありがとう!

この質問に適合するトリガーの有効期間と実行コンテキストに関する質問を追加しました。

PostgreSQL でのデータベース トリガーの実行コンテキスト

4

1 に答える 1

6

セッション設定だけを使用できる場合、一時テーブルは過剰に思えます。

postgresql.confバージョン 9.1までは、 custom_variable_classesパラメーターを使用してカスタム セッション変数を宣言する必要があり、デプロイに関しては少し面倒でした。

9.2以降、不要になりました。したがって、接続時に次のように発行できます。

SET myapp.myusername='foobar';

次に、トリガーまたは実際にはセッション内の任意の場所でSELECT current_setting('myapp.myusername')、またはSHOW myapp.myusername値が返されます。

于 2013-08-03T19:23:00.063 に答える