惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LINUX DO - 最新话题
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
T
Tenable Blog
T
Threatpost
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
D
Darknet – Hacking Tools, Hacker News & Cyber Security
K
Kaspersky official blog
Security Latest
Security Latest
P
Privacy & Cybersecurity Law Blog
Google Online Security Blog
Google Online Security Blog
SecWiki News
SecWiki News
P
Palo Alto Networks Blog
TaoSecurity Blog
TaoSecurity Blog
Webroot Blog
Webroot Blog
Spread Privacy
Spread Privacy
O
OpenAI News
The Last Watchdog
The Last Watchdog
P
Proofpoint News Feed
C
Check Point Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
人人都是产品经理
人人都是产品经理
S
Security @ Cisco Blogs
Scott Helme
Scott Helme
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
月光博客
月光博客
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
T
Troy Hunt's Blog
W
WeLiveSecurity
GbyAI
GbyAI
N
News | PayPal Newsroom
Y
Y Combinator Blog
C
Cisco Blogs
H
Help Net Security
The GitHub Blog
The GitHub Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 【当耐特】
Jina AI
Jina AI
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
云风的 BLOG
云风的 BLOG
小众软件
小众软件
N
News and Events Feed by Topic

Supabase Blog

AI Agents Know About Supabase. They Don't Always Use It Right. Custom OIDC Providers for Supabase Auth 100,000 GitHub stars Supabase docs over SSH Navigating Regional Network Blocks Supabase Joins the Stripe Projects Developer Preview Log Drains: Now available on Pro Supabase Storage: major performance, security, and reliability updates Supabase incident on February 12, 2026 Hydra joins Supabase X / Twitter OAuth 2.0 is now available for Supabase Auth BKND joins Supabase Supabase is now an official Claude connector Supabase PrivateLink is now available Introducing: Postgres Best Practices When to use Read Replicas vs. bigger compute Introducing TRAE SOLO integration with Supabase Supabase Security Retro: 2025 Sync Stripe Data to Your Supabase Database in One Click Building ChatGPT Apps with Supabase Edge Functions and mcp-use Own Your Observability: Supabase Metrics API Introducing iceberg-js: A JavaScript Client for Apache Iceberg Introducing Supabase for Platforms Adding Async Streaming to Postgres Foreign Data Wrappers Build "Sign in with Your App" using Supabase Auth Introducing Seven New Email Templates for Supabase Auth The new Supabase power for Kiro Introducing Supabase ETL Introducing Analytics Buckets Introducing Vector Buckets Snap, Inc. Launches Snap Cloud, Powered by Supabase Triplit joins Supabase Supabase Series E 1000 Y Combinator Founders Choose Supabase gm 👋 web3, welcome aboard to Sign in with Web3 (Solana, Ethereum) Announcing the Supabase Remote MCP Server Enterprise speed, enterprise standards with Bolt Cloud + Supabase PostgREST 13 Lovable Cloud + Supabase: The Default Platform for AI Builders Processing large jobs with Edge Functions, Cron, and Queues Defense in Depth for MCP Servers OrioleDB Patent: now freely available to the Postgres community Supabase Launch Week 15 Hackathon Winner Announcement The Vibe Coder's Guide to Supabase Environments Testing for Vibe Coders: From Zero to Production Confidence The Vibe Coding Master Checklist Vibe Coding: Best Practices for Prompting Supabase Auth: Build vs. Buy Top 10 Launches of Launch Week 15 Supabase Launch Week 15 Hackathon Storage: 10x Larger Uploads, 3x Cheaper Cached Egress, and 2x Egress Quota Persistent Storage and 97% Faster Cold Starts for Edge Functions Algolia Connector for Supabase New Observability Features in Supabase Improved Security Controls and A New Home for Security Introducing Branching 2.0 Stripe-To-Postgres Sync Engine as standalone Library Supabase Analytics Buckets with Iceberg Support Create a Supabase backend using Figma Make Introducing JWT Signing Keys Supabase UI: Platform Kit Build a Personalized AI Assistant with Postgres Announcing Multigres: Vitess for Postgres Building on open table formats Open Data Standards: Postgres, OTel, and Iceberg Simplifying back-end complexity with Supabase Data APIs PostgreSQL Event Triggers without superuser access Top 10 Launches of Launch Week 14 Supabase MCP Server Data API Routes to Nearest Read Replica Declarative Schemas for Simpler Database Management Realtime: Broadcast from Database Keeping Tabs on What's New in Supabase Studio Edge Functions: Deploy from the Dashboard + Deno 2.1 Automatic Embeddings in Postgres Introducing the Supabase UI Library Supabase Auth: Bring Your Own Clerk Postgres Language Server: Initial Release Migrating from Fauna to Supabase Migrating from the MongoDB Data API to Supabase Dedicated Poolers Postgres as a Graph Database: (Ab)using pgRouting AI Hackathon at Y Combinator Calendars in Postgres using Foreign Data Wrappers Supabase Launch Week 13 Hackathon Winners How to Hack the Base! Running Durable Workflows in Postgres using DBOS database.build v2: Bring-your-own-LLM Restore to a New Project Hack the Base! with Supabase Top 10 Launches of Launch Week 13 Supabase Queues High Performance Disk Supabase Cron Supabase CLI v2: Config as Code Supabase Edge Functions: Introducing Background Tasks, Ephemeral Storage, and WebSockets Supabase AI Assistant v2 OrioleDB Public Alpha Executing Dynamic JavaScript Code on Supabase with Edge Functions ClickHouse Partnership, improved Postgres Replication, and Disk Management
Simplifying Time-Based Queries with Range Columns
Tyler Shukert · 2024-07-11 · via Supabase Blog

Simplifying Time-Based Queries with Range Columns

When working on applications such as a reservation app or calendar app, you need to store the start time and end time of an event. You may also need to query events occurring in a specific time frame or ensure that certain events do not overlap. If you have a table with two separate columns start_at and end_at to hold the beginning and end of an event, it might be hard to perform advanced queries or add constraints to prevent overlaps. This article will show how range-type columns could provide helpful query functionalities and advanced constraints to avoid overlapping.

Traditionally, when dealing with events or periods, developers often use two separate columns to represent the start and end of a range. For example:


_10

create table reservations (

_10

id serial primary key,

_10

title text,

_10

start_at timestamptz,

_10

end_at timestamptz

_10

);


While this approach works, it has a few drawbacks:

  1. Querying Complexity: Writing queries to find overlapping events or events within a specific period becomes complex and error-prone.
  2. Data Integrity: Ensuring that reservations do not overlap is difficult.

Range types are data types in Postgres that hold the beginning and end of a range of a base type. The range of int4 is int4range, the range of timestamptz is tstzrange, and the range of date is daterange. Each range has a start value, an end value, and either square brackets [] or parenthesis () surrounding them. A bracket means the end is inclusive, and a parenthesis means the end is exclusive. An int4range of [2,5) represents a range of integers from 2 including it to 5 excluding it, so 2, 3, and 4.

Querying range columns#

Using these range values, we can create a reservation table like the following:


_10

create table reservations (

_10

id serial primary key,

_10

title text,

_10

duration tstzrange

_10

);


Using tstzrange instead of two timestamptz columns have a few advantages. First, it allows us to easily query reservations that overlap with a provided range using the && operator. Look at the following select query:


_10

select *

_10

from reservations

_10

where duration && '[2024-07-04 16:00, 2024-07-04 19:00)';


This query returns rows where the duration overlaps with [2024-07-04 16:00, 2024-07-04 19:00). For example, a row with [2024-07-04 18:00, 2024-07-04 21:00) will be returned, but a row with [2024-07-04 20:00, 2024-07-04 22:00) will not be returned. The overlaps operator can be used when finding reservations or events in a given period.

Postgres provides more range-specific operators. The official Postgres documentation provides a complete list of range operators.

Adding constraints on range columns#

When working on a reservations app, you might want to ensure there are no overlapping reservations. Range columns make it easy to add such constraints. The following SQL statement adds an exclude constraint that prevents new inserts/ updates from overlapping on any of the existing reservations.


_10

alter table reservations

_10

add constraint exclude_duration exclude

_10

using gist (duration with &&)


With the above constraint, the second insert on the following SQL statements fails because the duration overlaps with the first insert.


_10

-- Add a first reservation

_10

insert into reservations (title, duration)

_10

values ('Tyler Dinner', '[2024-07-04 18:00, 2024-07-04 21:00)');

_10

_10

-- The following insert fails because the duration overlaps with the above

_10

insert into reservations (title, duration)

_10

values ('Thor Dinner', '[2024-07-04 20:00, 2024-07-04 22:00)');


Now, the exclusion constraint prevents any reservations from overlapping, but in the real world, a single reservations table typically holds reservations for different restaurants and tables within a restaurant, and just because a single reservation was made at a restaurant, it does not mean the entire restaurant is booked. Postgres can create such constraints where an insert or an update is disallowed only if a specific other column matches and the range overlaps.

Let’s say we had a table_id column in our reservations table. This table_id could represent a single table in various restaurants this database holds.


_10

create table reservations (

_10

id serial primary key,

_10

title text,

_10

table_id int4,

_10

duration tstzrange

_10

);


With a table_id column in place, we can add a constraint to ensure that reservations on the same table do not overlap. The constraint requires the btree_gist extension.


_10

-- Enable the btree_gist index required for the constraint.

_10

create extension btree_gist

_10

_10

-- Add a constraint to prevent overlaps with the same table_id

_10

alter table reservations

_10

add constraint exclude_duration

_10

exclude using gist (table_id WITH =, duration WITH &&);


With this simple constraint, no two reservations will overlap with each other with the same table_id. If we run the following inserts, the second insert will fail because it is trying to book the same table as the first insert while the duration overlaps.


_11

-- Add a first reservation

_11

insert into reservations (title, table_id, duration)

_11

values ('Tyler Dinner', 1, '[2024-07-04 18:00, 2024-07-04 21:00)');

_11

_11

-- Insert fails, because table 1 is taken from 18:00 - 21:00

_11

insert into reservations (title, table_id, duration)

_11

values ('Thor Dinner', 1, '[2024-07-04 20:00, 2024-07-04 22:00)');

_11

_11

-- Insert succeeds because table 2 is not taken by anyone

_11

insert into reservations (title, table_id, duration)

_11

values ('Thor Dinner', 2, '[2024-07-04 20:00, 2024-07-04 22:00)');


And that is how to create an air-tight table that holds reservations.

Postgres's range columns offer a solution for handling range data in applications like reservation systems. They simplify queries with specific operators such as && and improve data integrity by enabling constraints to prevent overlaps. Range columns provide an alternative to traditional two-column approaches for representing periods. By leveraging these features, developers can create more sophisticated and reliable applications with less code.