sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur hittar jag senaste gången en PostgreSQL-databas har uppdaterats?

Du kan skriva en trigger att köras varje gång en infogning/uppdatering görs på en viss tabell. Den vanliga användningen är att ställa in en "created" eller "last_updated" kolumn i raden till den aktuella tiden, men du kan också uppdatera tiden på en central plats om du inte vill ändra de befintliga tabellerna.

Så till exempel ett typiskt sätt är följande:

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

För att sedan hitta den senaste uppdateringstiden måste du välja "MAX(last_updated)" från varje tabell du spårar och ta den största av dessa, t.ex.:

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

För tabeller med en seriell (eller liknande genererad) primärnyckel kan du försöka undvika den sekventiella genomsökningen för att hitta den senaste uppdateringstiden genom att använda primärnyckelindexet, eller så skapar du index på last_updated.

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

Observera att detta kan ge lite felaktiga resultat om ID:n inte är riktigt sekventiella, men hur mycket noggrannhet behöver du? (Tänk på att transaktioner innebär att rader kan bli synliga för dig i en annan ordning än när de skapas.)

Ett alternativt tillvägagångssätt för att undvika att lägga till "uppdaterade" kolumner i varje tabell är att ha en central tabell att lagra uppdateringstidsstämplar i. Till exempel:

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

Detta kommer att ge dig en tabell med en rad för varje tabelluppdatering:du kan sedan bara göra:

SELECT MAX(updated) FROM update_log

För att få den senaste uppdateringstiden. (Du kan dela upp detta efter tabell om du vill). Den här tabellen kommer naturligtvis bara att växa:antingen skapa ett index på "uppdaterad" (vilket borde göra att få den senaste ganska snabbt) eller trunkera den med jämna mellanrum om det passar ditt användningsfall, (t.ex. ta ett exklusivt lås på bordet, hämta den senaste uppdateringstiden och trunkera den sedan om du behöver kontrollera med jämna mellanrum om ändringar har gjorts).

Ett alternativt tillvägagångssätt - vilket kan vara vad folket på forumet menade - är att ställa in 'log_statement =mod' i databaskonfigurationen (antingen globalt för klustret, eller på databasen eller användaren du behöver spåra) och sedan alla uttalanden som modifiera databasen kommer att skrivas till serverloggen. Du måste sedan skriva något utanför databasen för att skanna serverloggen, filtrera bort tabeller som du inte är intresserad av, etc.



  1. Få rangordning på rad i OrderBy beskrivande vältalig fråga, hur kan jag få den här frågan att fungera i laravel 5.5 vältaliga?)

  2. Tvetydigt kolumnfel i Laravel 4

  3. Hur man bevarar ordningen för barn att visas efter sina föräldrar

  4. Hur kan jag konvertera geometridata till geografidata i MS SQL Server 2008?