Bạn có thể viết một trình kích hoạt để chạy mỗi khi chèn / cập nhật được thực hiện trên một bảng cụ thể. Cách sử dụng phổ biến là đặt cột "đã tạo" hoặc "cập nhật cuối cùng" của hàng thành thời gian hiện tại, nhưng bạn cũng có thể cập nhật thời gian ở vị trí trung tâm nếu bạn không muốn thay đổi các bảng hiện có.
Vì vậy, ví dụ một cách điển hình là cách sau:
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();
Sau đó, để tìm thời gian cập nhật cuối cùng, bạn cần chọn "MAX (last_updated)" từ mỗi bảng bạn đang theo dõi và lấy giá trị lớn nhất trong số đó, ví dụ:
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
Đối với các bảng có khóa chính nối tiếp (hoặc được tạo tương tự), bạn có thể thử tránh quét tuần tự để tìm thời gian cập nhật mới nhất bằng cách sử dụng chỉ mục khóa chính hoặc bạn tạo chỉ mục trên last_updated.
-- get timestamp of row with highest id
SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1
Lưu ý rằng điều này có thể cho kết quả hơi sai trong trường hợp ID không hoàn toàn liên tục, nhưng bạn cần độ chính xác bao nhiêu? (Lưu ý rằng các giao dịch có nghĩa là các hàng có thể hiển thị với bạn theo một thứ tự khác với chúng được tạo.)
Một cách tiếp cận thay thế để tránh thêm các cột 'đã cập nhật' vào mỗi bảng là có một bảng trung tâm để lưu trữ các dấu thời gian cập nhật. Ví dụ:
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();
Thao tác này sẽ cung cấp cho bạn một bảng với một hàng cho mỗi lần cập nhật bảng:sau đó bạn có thể thực hiện:
SELECT MAX(updated) FROM update_log
Để có được thời gian cập nhật cuối cùng. (Bạn có thể chia nó ra theo bảng nếu bạn muốn). Bảng này tất nhiên sẽ tiếp tục phát triển:hoặc tạo một chỉ mục trên 'đã cập nhật' (điều này sẽ làm cho việc nhận bản mới nhất khá nhanh) hoặc cắt ngắn nó theo định kỳ nếu phù hợp với trường hợp sử dụng của bạn, (ví dụ:lấy một ổ khóa độc quyền trên bảng, lấy thời gian cập nhật mới nhất, sau đó cắt bớt thời gian đó nếu bạn cần kiểm tra định kỳ xem các thay đổi đã được thực hiện hay chưa).
Một cách tiếp cận thay thế - có thể là ý của mọi người trên diễn đàn - là đặt 'log_statement =mod' trong cấu hình cơ sở dữ liệu (toàn cục cho cụm hoặc trên cơ sở dữ liệu hoặc người dùng bạn cần theo dõi) và sau đó tất cả các câu lệnh sửa đổi cơ sở dữ liệu sẽ được ghi vào nhật ký máy chủ. Sau đó, bạn sẽ cần viết một cái gì đó bên ngoài cơ sở dữ liệu để quét nhật ký máy chủ, lọc ra các bảng mà bạn không quan tâm, v.v.