首页 > 数据库 > mysql教程 > PostgreSQL 的 tsrange 如何简化营业时间查询?

PostgreSQL 的 tsrange 如何简化营业时间查询?

DDD
发布: 2025-01-05 02:04:41
原创
817 人浏览过

How Can PostgreSQL's `tsrange` Simplify Queries for Business Hours of Operation?

使用 tsrange 在 PostgreSQL 中进行操作查询的时间

简介

在 PostgreSQL 中,时间特定实体的操作可以存储为整数列对,例如 opens_on 和closes_on 代表工作日,opens_at 和 closes_at 代表一天中的时间。然而,由于时间表中潜在的重叠和不规则性,对此类数据执行查询可能会很复杂。

使用 tsrange 的替代方法

为了解决这些复杂性,需要一种更高效的方法该方法涉及使用 tsrange 数据类型,它表示一系列没有时区的时间戳。通过利用 tsrange,我们可以将运行时间存储为范围集。这种方法有几个好处:

数据结构

CREATE TABLE hoo (
  hoo_id  serial PRIMARY KEY,
  shop_id int NOT NULL, -- REFERENCES shop(shop_id)
  hours   tsrange NOT NULL
);
登录后复制

例如,如果商店从周三下午 6 点到周四早上 5 点(UTC)营业,则相应的营业时间范围会为:

'[1996-01-03 18:30, 1996-01-04 05:00]'
登录后复制

函数

CREATE OR REPLACE FUNCTION f_hoo_time(timestamptz)
  RETURNS timestamp
  LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
$func$
SELECT timestamp '1996-01-01' + ( AT TIME ZONE 'UTC' - date_trunc('week',  AT TIME ZONE 'UTC'))
$func$;
登录后复制
CREATE OR REPLACE FUNCTION f_hoo_hours(_from timestamptz, _to timestamptz)
  RETURNS TABLE (hoo_hours tsrange)
  LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE COST 500 ROWS 1 AS
$func$
DECLARE
   ts_from timestamp := f_hoo_time(_from);
   ts_to   timestamp := f_hoo_time(_to);
BEGIN
   -- Perform sanity checks and split ranges at Sunday midnight if necessary.
   ...
END
$func$;
登录后复制

查询

原始复杂查询现在可以是替换为以下简化的语句:

SELECT *
FROM hoo
WHERE hours @> f_hoo_time(now());
登录后复制

索引

为了优化查询性能,可以创建按小时的 SP-GiST 索引:

CREATE INDEX hoo_hours_spgist_idx on hoo USING spgist (hours);
登录后复制

性能

这种使用 SP-GiST 索引的方法提供了显着的性能改进,尤其是在搜索大量结果时。它优于其他索引策略,并减少了低结果计数和高结果计数的执行时间。

以上是PostgreSQL 的 tsrange 如何简化营业时间查询?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板