无时间字段时如何查询数据表中近一天新增或修改的数据行?
无显式时间字段时查询近一天变更数据的可行方案
- 优先利用数据库内置的隐藏元数据列查询,主流关系型数据库默认都会携带记录行变更信息的系统伪列,无需用户手动创建字段:
- MySQL(InnoDB引擎):8.0及以上版本可直接使用隐藏列
ROW_START获取行最近修改时间,查询示例:
5.7版本可通过隐藏列SELECT * FROM 表名 WHERE ROW_START > DATE_SUB(NOW(), INTERVAL 1 DAY);DB_TRX_ID关联事务信息表获取变更时间,需保证undo日志保留时间足够。 - PostgreSQL:使用隐藏列
xmin(记录行最后变更的事务ID)结合pg_xact_commit_timestamp()函数转换为时间戳,需提前开启track_commit_timestamp = on参数,查询示例:SELECT * FROM 表名 WHERE pg_xact_commit_timestamp(xmin) > NOW() - INTERVAL '1 day'; - Oracle:使用伪列
ORA_ROWSCN获取行最后修改的SCN号,通过SCN_TO_TIMESTAMP()转换为时间戳,查询示例:SELECT * FROM 表名 WHERE SCN_TO_TIMESTAMP(ORA_ROWSCN) > SYSDATE - 1; - SQL Server:针对默认开启的时态表,使用隐藏列
sys_start_time查询,示例:SELECT * FROM 表名 WHERE sys_start_time > DATEADD(DAY, -1, GETUTCDATE());
- MySQL(InnoDB引擎):8.0及以上版本可直接使用隐藏列
- 若数据库未开启上述隐藏列相关配置,可通过全量行对比的方式获取变更:
提前生成一天前该表的全量行校验快照,对每行所有字段拼接后做哈希校验,将当前表的校验结果和历史快照对比,校验值不一致的即为变更行,校验查询示例:SELECT 主键列, CRC32(CONCAT_WS('|', 列1, 列2, 列3, ... 剩余所有列)) AS row_checksum FROM 表名; - 若数据库开启了事务日志(binlog/redo log/归档日志等),可解析近24小时的事务日志,筛选所有对该表执行
INSERT/UPDATE/DELETE操作的记录,即可得到完整的变更数据。
注意:上述方案的可用性和精度受数据库版本、引擎配置、日志保留周期限制,若业务有高频查询行变更时间的需求,建议后续在表中新增显式
update_time字段并设置ON UPDATE CURRENT_TIMESTAMP自动更新,查询效率和稳定性远高于依赖隐藏列或日志的方案。
内容的提问来源于stack exchange,提问作者Whisht
相关产品推荐
相关产品推荐

