sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLデータベースが最後に更新された時刻を確認するにはどうすればよいですか?

    トリガー を作成できます 特定のテーブルで挿入/更新が行われるたびに実行します。一般的な使用法は、行の「created」または「last_updated」列を現在の時刻に設定することですが、既存のテーブルを変更したくない場合は、中央の場所で時刻を更新することもできます。

    したがって、たとえば、一般的な方法は次のとおりです。

    CREATE FUNCTION stamp_updated() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
    BEGIN
      NEW.last_updated := now();
      RETURN NEW;
    END
    $$;
    -- repeat for each table you need to track:
    ALTER TABLE sometable ADD COLUMN last_updated TIMESTAMP;
    CREATE TRIGGER sometable_stamp_updated
      BEFORE INSERT OR UPDATE ON sometable
      FOR EACH ROW EXECUTE PROCEDURE stamp_updated();
    

    次に、最終更新時刻を見つけるには、追跡している各テーブルから「MAX(last_updated)」を選択し、それらの中で最大のものを取得する必要があります。例:

    SELECT MAX(max_last_updated) FROM (
      SELECT MAX(last_updated) AS max_last_updated FROM sometable
      UNION ALL
      SELECT MAX(last_updated) FROM someothertable
    ) updates
    

    シリアル(または同様に生成された)主キーを持つテーブルの場合、主キーインデックスを使用して最新の更新時刻を見つけるためのシーケンシャルスキャンを回避するか、last_updatedにインデックスを作成できます。

    -- get timestamp of row with highest id
    SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1
    

    IDが完全に連続していない場合、これによりわずかに間違った結果が得られる可能性があることに注意してください。ただし、どの程度の精度が必要ですか。 (トランザクションとは、作成されている行とは異なる順序で行が表示されることを意味することに注意してください。)

    各テーブルに「更新された」列が追加されないようにする別の方法は、更新タイムスタンプを格納する中央テーブルを用意することです。例:

    CREATE TABLE update_log(table_name text PRIMARY KEY, updated timestamp NOT NULL DEFAULT now());
    CREATE FUNCTION stamp_update_log() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
    BEGIN
      INSERT INTO update_log(table_name) VALUES(TG_TABLE_NAME);
      RETURN NEW;
    END
    $$;
    -- Repeat for each table you need to track:
    CREATE TRIGGER sometable_stamp_update_log
     AFTER INSERT OR UPDATE ON sometable
     FOR EACH STATEMENT EXECUTE stamp_update_log();
    

    これにより、テーブルの更新ごとに1行のテーブルが表示されます。次の操作を実行できます。

    SELECT MAX(updated) FROM update_log
    

    最終更新時刻を取得します。 (必要に応じて、これをテーブルごとに分割できます)。もちろん、このテーブルは成長し続けます。「updated」でインデックスを作成するか(最新のインデックスを非常に高速に取得できるようにする必要があります)、ユースケースに適合する場合は定期的に切り捨てます(たとえば、テーブルを排他的にロックします。最新の更新時刻を取得し、変更が加えられているかどうかを定期的に確認する必要がある場合は、それを切り捨てます。

    別のアプローチ(フォーラムの人々が意味するかもしれない)は、データベース構成(クラスターに対してグローバルに、または追跡する必要のあるデータベースまたはユーザーに対して)で「log_statement =mod」を設定し、次にすべてのステートメントを設定することです。データベースを変更すると、サーバーログに書き込まれます。次に、サーバーログをスキャンしたり、関心のないテーブルを除外したりするために、データベースの外部に何かを書き込む必要があります。



    1. ストアドプロシージャ名の最大長があるのはなぜですか?

    2. ORA-01950:表領域'USERS'に対する権限がありません

    3. SQLでの制約の確認

    4. HerokuでのSinatra/Haml/DataMapperのPostgresエラー