PostgreSQL常用range类型包括int4range、int8range、numrange、tsrange、tstzrange和daterange,适用于不同数据类型的区间存储;可通过内置构造函数或文本格式插入数据,支持包含、重叠、左侧等丰富操作符,并可结合GIST索引高效查询,还允许自定义如floatrange等新类型,广泛用于时间范围、数值区间等场景。

PostgreSQL 的 range 类型 是一种专门用于表示值的区间的数据类型,非常适合存储如时间范围、数值区间等连续数据。它让区间操作变得高效且语义清晰,避免了手动维护起始和结束字段的复杂性。
常用 range 类型有哪些?
PostgreSQL 内置了几种常用的区间类型,对应不同的基础数据类型:
- int4range:32位整数区间,例如价格范围、年龄区间
- int8range:64位整数区间
- numrange:任意精度数值(numeric)区间,适合金额等高精度场景
- tsrange:不带时区的时间戳区间,常用于时间段记录
- tstzrange:带时区的时间戳区间,推荐用于分布式系统
- daterange:日期类型的区间
[2024-01-01, 2024-01-31] 表示一整个月的日期范围,包含首尾。
如何定义和插入区间数据?
可以在建表时直接使用 range 类型字段:
CREATE TABLE reservations ( id serial PRIMARY KEY, room_number int, period tstzrange );
插入区间数据时,可以使用内置函数 range constructor 或文本格式:
INSERT INTO reservations (room_number, period)
VALUES
(101, '[2024-06-01 09:00, 2024-06-01 17:00)'),
(102, tstzrange('2024-06-02 10:00', '2024-06-02 18:00', '[)'));
注意括号含义:[ 表示包含端点,
) 表示不包含端点。
默认是左闭右开
[),可根据需要调整。
支持哪些区间操作?
range 类型提供丰富的操作符和函数,便于查询和判断:
-
@>:是否包含某个值或区间
period @> '2024-06-01 12:00'::timestamptz - :是否被包含
-
&&:是否重叠
period && '[2024-06-01 10:00, 2024-06-01 12:00)' - :是否完全在左侧(不重叠)
- +:合并两个重叠或相邻的区间
- lower() 和 upper():获取区间的下界和上界
结合 GIST 或 SP-GIST 索引,这些操作能高效执行:
CREATE INDEX idx_reservations_period ON reservations USING gist (period);
自定义 range 类型(可选进阶)
如果内置类型不够用,比如想为 float 创建区间,可通过 CREATE TYPE 定义:
CREATE TYPE floatrange AS RANGE ( subtype = double precision, subtype_diff = float8mi );
注意:必须指定 subtype_diff 以支持长度估算,这对索引性能很重要。
基本上就这些。合理使用 range 类型能让区间逻辑更清晰,查询更安全,还能借助索引提升性能,特别适合排班、预订、有效期管理等场景。










