sql >> Database >  >> RDS >> PostgreSQL

Hoe vind ik de laatste keer dat een PostgreSQL-database is bijgewerkt?

Je kunt een trigger schrijven om elke keer dat een invoeging/update op een bepaalde tafel wordt uitgevoerd, uit te voeren. Het gebruikelijke gebruik is om een ​​kolom "gemaakt" of "laatst bijgewerkt" van de rij in te stellen op de huidige tijd, maar u kunt de tijd ook op een centrale locatie bijwerken als u de bestaande tabellen niet wilt wijzigen.

Een typische manier is bijvoorbeeld de volgende:

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();

Om vervolgens de laatste updatetijd te vinden, moet u "MAX(last_updated)" selecteren uit elke tabel die u bijhoudt en de grootste daarvan nemen, bijvoorbeeld:

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

Voor tabellen met een seriële (of vergelijkbaar gegenereerde) primaire sleutel, kunt u proberen de sequentiële scan te vermijden om de laatste updatetijd te vinden door de primaire sleutelindex te gebruiken, of u maakt indices op last_updated.

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

Merk op dat dit enigszins verkeerde resultaten kan geven in het geval dat ID's niet helemaal opeenvolgend zijn, maar hoeveel nauwkeurigheid heb je nodig? (Houd er rekening mee dat transacties betekenen dat rijen voor u zichtbaar kunnen worden in een andere volgorde dan wanneer ze zijn gemaakt.)

Een alternatieve benadering om te voorkomen dat er 'bijgewerkte' kolommen aan elke tabel worden toegevoegd, is om een ​​centrale tabel te hebben om tijdstempels voor updates op te slaan. Bijvoorbeeld:

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();

Dit geeft je een tabel met een rij voor elke tafelupdate:je kunt dan gewoon doen:

SELECT MAX(updated) FROM update_log

Om de laatste updatetijd te krijgen. (U kunt dit desgewenst per tabel uitsplitsen). Deze tabel zal natuurlijk gewoon blijven groeien:maak ofwel een index op 'updated' (waardoor de nieuwste vrij snel wordt opgehaald) of kap deze periodiek af als dat past bij uw gebruikssituatie (bijvoorbeeld een exclusief slot op de tafel nemen, de laatste updatetijd ophalen en deze vervolgens inkorten als u regelmatig moet controleren of er wijzigingen zijn aangebracht).

Een alternatieve benadering - wat misschien is wat de mensen op het forum bedoelden - is om 'log_statement =mod' in te stellen in de databaseconfiguratie (ofwel globaal voor het cluster, of op de database of gebruiker die u moet volgen) en vervolgens alle instructies die wijzigen van de database wordt naar het serverlogboek geschreven. U moet dan iets buiten de database schrijven om het serverlogboek te scannen, tabellen uit te filteren waarin u niet geïnteresseerd bent, enz.



  1. Parameters doorgeven aan een JDBC PreparedStatement

  2. Kun je de ene alias door de andere delen in MySQL?

  3. Een dynamisch gegenereerde draaitabel in een tijdelijke tabel krijgen

  4. Booleaanse waarde retourneren van orakelfunctie