PostgreSQL

关注公众号 jb51net

关闭
首页 > 数据库 > PostgreSQL > PostgreSQL moddatetime扩展

PostgreSQL中扩展moddatetime的使用

作者:文牧之

PostgreSQL的moddatetime扩展通过触发器自动维护时间戳字段,轻量高效,适用于审计日志和多租户系统,具有一定的参考价值,感兴趣的可以了解一下

moddatetime 是 PostgreSQL 的一个内置扩展,用于自动维护表的最后修改时间字段。这个扩展可以自动更新指定字段为当前时间戳,非常适合需要跟踪记录最后修改时间的应用场景。

一、moddatetime 基本功能

核心特性

二、安装与启用

1. 安装扩展

-- 连接到目标数据库后执行
CREATE EXTENSION IF NOT EXISTS moddatetime;

2. 验证安装

-- 检查已安装扩展
SELECT * FROM pg_extension WHERE extname = 'moddatetime';

-- 查看扩展函数
\df moddatetime()

三、基本使用方法

1. 创建带有时间戳字段的表

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    content TEXT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    modified_at TIMESTAMP  -- 这个字段将由moddatetime自动维护
);

2. 创建触发器

-- 设置modified_at字段自动更新
CREATE TRIGGER update_document_modtime
BEFORE UPDATE ON documents
FOR EACH ROW
EXECUTE FUNCTION moddatetime(modified_at);

四、高级用法示例

1. 多字段自动更新

-- 如果需要同时维护created_at和modified_at
CREATE OR REPLACE FUNCTION update_timestamps()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        NEW.created_at = NOW();
        NEW.modified_at = NOW();
    ELSIF TG_OP = 'UPDATE' THEN
        NEW.modified_at = NOW();
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_update_timestamps
BEFORE INSERT OR UPDATE ON documents
FOR EACH ROW
EXECUTE FUNCTION update_timestamps();

2. 条件性更新时间戳

-- 只在特定列变更时更新时间戳
CREATE OR REPLACE FUNCTION conditional_moddatetime()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.content IS DISTINCT FROM OLD.content OR NEW.title IS DISTINCT FROM OLD.title THEN
        NEW.modified_at = NOW();
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_conditional_modtime
BEFORE UPDATE ON documents
FOR EACH ROW
EXECUTE FUNCTION conditional_moddatetime();

五、实际应用场景

1. 审计日志辅助

-- 结合审计表记录完整修改历史
CREATE TABLE document_audit (
    audit_id BIGSERIAL PRIMARY KEY,
    operation CHAR(1) NOT NULL,
    document_id INT NOT NULL,
    changed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    old_data JSONB,
    new_data JSONB
);

CREATE OR REPLACE FUNCTION log_document_changes()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'UPDATE' THEN
        INSERT INTO document_audit(operation, document_id, old_data, new_data)
        VALUES ('U', OLD.id, to_jsonb(OLD), to_jsonb(NEW));
    ELSIF TG_OP = 'DELETE' THEN
        INSERT INTO document_audit(operation, document_id, old_data)
        VALUES ('D', OLD.id, to_jsonb(OLD));
    ELSIF TG_OP = 'INSERT' THEN
        INSERT INTO document_audit(operation, document_id, new_data)
        VALUES ('I', NEW.id, to_jsonb(NEW));
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_document_audit
AFTER INSERT OR UPDATE OR DELETE ON documents
FOR EACH ROW
EXECUTE FUNCTION log_document_changes();

2. 多租户系统中的应用

CREATE TABLE tenant_records (
    id BIGSERIAL PRIMARY KEY,
    tenant_id INT NOT NULL,
    record_data JSONB NOT NULL,
    created_by INT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_by INT,
    updated_at TIMESTAMP,
    FOREIGN KEY (tenant_id) REFERENCES tenants(id)
);

CREATE OR REPLACE FUNCTION update_tenant_record_meta()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        NEW.created_at = NOW();
    ELSIF TG_OP = 'UPDATE' THEN
        NEW.updated_at = NOW();
        NEW.updated_by = current_setting('app.current_user_id')::INT;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_tenant_record_meta
BEFORE INSERT OR UPDATE ON tenant_records
FOR EACH ROW
EXECUTE FUNCTION update_tenant_record_meta();

六、性能考虑与优化

1. 触发器开销分析

2. 批量操作处理

-- 批量更新时临时禁用触发器
ALTER TABLE documents DISABLE TRIGGER update_document_modtime;

-- 执行批量更新操作
UPDATE documents SET content = content || '\nUpdated' 
WHERE id BETWEEN 1000 AND 2000;

-- 手动设置修改时间并重新启用触发器
UPDATE documents SET modified_at = NOW() 
WHERE id BETWEEN 1000 AND 2000 AND modified_at IS NULL;

ALTER TABLE documents ENABLE TRIGGER update_document_modtime;

七、与其他方法的比较

方法优点缺点
moddatetime 扩展简单易用,标准化功能较基础
自定义触发器高度灵活,可定制逻辑需要自行维护代码
应用层控制业务逻辑可见容易遗漏更新
监听逻辑解码不侵入业务代码配置复杂,延迟较高

八、最佳实践建议

moddatetime 是PostgreSQL中维护最后修改时间的轻量级解决方案,特别适合需要简单可靠地跟踪记录变更时间的应用场景。对于更复杂的需求,可以考虑结合自定义触发器或专门的审计解决方案。

到此这篇关于PostgreSQL中扩展moddatetime的使用的文章就介绍到这了,更多相关PostgreSQL moddatetime扩展内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文