You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Key-set分页中JavaScript时间精度不足引发的PostgreSQL查询异常

Key-set分页中的时间精度匹配问题

在实现Key-set Pagination功能时遇到以下问题:从API获取的timestamp仅支持毫秒精度,这是JavaScript Date的固有精度限制导致的,但数据库(PostgreSQL v15)存储的时间精度更高,最终引发分页查询匹配异常。

数据库Schema(PostgreSQL v15)

CREATE TABLE IF NOT EXISTS public.activities
(
    id uuid NOT NULL DEFAULT gen_random_uuid(),    
    created_at timestamp with time zone DEFAULT now(),
    PRIMARY KEY (id)
);

CREATE INDEX activities_created_at_id ON activities (created_at, id);

排序规则

以下是按created_at asc、id asc排序后的表数据:

select id, created_at from activities order by created_at asc, id asc;
idcreated_at
e34d5557-43d7-4f81-802b-791c213ea5cb2024-03-14T07:23:56.474123Z
ea7e9cad-89f2-4610-898f-62a04e8b53312024-03-14T07:23:56.474123Z
0cf727a8-5efc-454b-ba1b-ea301e2b1a822024-03-14T07:23:56.474222Z
10f1dd9b-2cd8-40bb-a199-2d9c922d07b12024-03-14T07:23:56.474222Z
3c00c38e-45b9-4c3c-9d05-fc1ca2177dbe2024-03-14T07:23:56.474222Z
ac31e591-d4ea-4ef5-956a-c07bd043d9ea2024-03-14T07:23:56.474222Z
b9b33ca5-2cd1-490b-a6be-d28784f75b2a2024-03-14T07:23:56.474222Z
bc9763d0-6d24-4fbf-bc23-7eff1589280a2024-03-14T07:23:56.474222Z
c442f6ea-61bf-42d4-aa85-4eab1d95f5692024-03-14T07:23:56.474222Z
ded826f7-65f0-4d23-9366-049823ba49ec2024-03-14T07:23:56.474222Z

精度不匹配问题

由于JavaScript无法支持毫秒以上的精度,传入查询的时间精度低于数据库存储值,导致以下查询返回了所有数据:

select id, created_at from activities
where (created_at, id) > ('2024-03-14T07:23:56.474Z', 'b9b33ca5-2cd1-490b-a6be-d28784f75b2a')
order by created_at asc, id asc;
idcreated_at
e34d5557-43d7-4f81-802b-791c213ea5cb2024-03-14T07:23:56.474Z
ea7e9cad-89f2-4610-898f-62a04e8b53312024-03-14T07:23:56.474Z
0cf727a8-5efc-454b-ba1b-ea301e2b1a822024-03-14T07:23:56.474Z
10f1dd9b-2cd8-40bb-a199-2d9c922d07b12024-03-14T07:23:56.474Z
3c00c38e-45b9-4c3c-9d05-fc1ca2177dbe2024-03-14T07:23:56.474Z
ac31e591-d4ea-4ef5-956a-c07bd043d9ea2024-03-14T07:23:56.474Z
b9b33ca5-2cd1-490b-a6be-d28784f75b2a2024-03-14T07:23:56.474Z
bc9763d0-6d24-4fbf-bc23-7eff1589280a2024-03-14T07:23:56.474Z
c442f6ea-61bf-42d4-aa85-4eab1d95f5692024-03-14T07:23:56.474Z
ded826f7-65f0-4d23-9366-049823ba49ec2024-03-14T07:23:56.474Z

临时方案:用date_trunc限制查询精度

这个方法能得到预期结果,但需要根据字段类型动态构建查询,可能存在性能问题,因此不想仅依赖此方案:

select id, created_at from activities
where (date_trunc('milliseconds', created_at::timestamptz), id) < (date_trunc('milliseconds', '2024-03-14T07:23:56.474Z'::timestamptz), 'b9b33ca5-2cd1-490b-a6be-d28784f75b2a')
order by created_at desc, id desc;
idcreated_at
ac31e591-d4ea-4ef5-956a-c07bd043d9ea2024-03-14T07:23:56.474Z
3c00c38e-45b9-4c3c-9d05-fc1ca2177dbe2024-03-14T07:23:56.474Z
10f1dd9b-2cd8-40bb-a199-2d9c922d07b12024-03-14T07:23:56.474Z
0cf727a8-5efc-454b-ba1b-ea301e2b1a822024-03-14T07:23:56.474Z

寻求替代方案

目前已知一种解决方案是在客户端与服务端之间传输bigint字符串,但希望在进行耗时改造前,找到其他更优的方案,恳请社区提供建议。

内容的提问来源于stack exchange,提问作者Bjørn Bråthen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 19:18:10