4

postgres でデータベースロールに外部キーを追加するにはどうすればよいですか?

CREATE TABLE "public"."role_info" (
    "last_login" timestamptz,
    "user" name,
    CONSTRAINT "role_info" FOREIGN KEY ("user") REFERENCES "pg_catalog"."pg_authid" ("rolname") ON UPDATE NO ACTION ON DELETE NO ACTION
 )
 WITH (OIDS=FALSE);

これは、許可が拒否されたことを返しています。

4

1 に答える 1

7

あなたはそうしない。現在の実装では、システムカタログを参照する外部キーを追加することはできません。

pg_role一部のカタログでその制限が後で緩和されたとしても、すべてのDBで共有されているようなグローバルカタログは制限されたままになる可能性があります。

トリガーを使用して関係を一方向に適用し、存在しないシステムカタログエントリを参照する値を追加しないようにすることができます。ただし、カタログエントリの削除を停止することはできないため、有用性は限られています。

PostgreSQL12リリースを中心に2019を編集します。

これができない理由はたくさんあります。

システムの特殊なケースのシステムカタログ関係は、それらを特別に動作させるいくつかの方法で行われます。

  • ユーザーリレーションでは許可されておらず、トランザクションの中止時にロールバックできないインプレース更新を行う場合があります
  • 通常、間接参照とキャッシングのレイヤー(syscacheとrelcache)を介してそれらにアクセスします。
  • PostgreSQLの高レベルの機能の束をサポートしない特別な軽量アクセス方式(genam)を介してそれらを更新し、パフォーマンス、メモリ使用量、およびコードの複雑さの理由から、いくつかの単純化された仮定を行います。

さらに、それの場合、あなたがチェックすることによって見ることができるように、pg_catalog.pg_authidそれは共有された関係select relisshared from pg_catalog.pg_class where oid = 'pg_catalog.pg_authid'::regclassです。つまり、同じテーブルの内容がPostgreSQLインスタンス(「クラスター」またはデータディレクトリ)上のすべてのデータベースにマップされます。pg_catalog.pg_classFKを参照する関係は、1つのデータベースにのみ存在し、その行を含むヒープも存在するため、FKを使用する賢明な方法はありませんが、参照されるヒープは すべてのデータベースpg_catalog.pg_authidにマップされます。あるデータベースに接続されたpostgresバックエンドは、FK制約が別のデータベースに存在することすら知らず、チェックする方法もありません。

于 2013-02-25T13:26:28.243 に答える