❌ اگر در PostgreSQL هنوز برای ذخیره بازههای زمانی از دو ستون start_at و end_at استفاده میکنید، شاید وقت آن رسیده با Range Types آشنا شوید.
جالب است بدانید این قابلیت از PostgreSQL 9.2 (سال ۲۰۱۲) وجود دارد، اما هنوز هم یکی از ویژگیهای کمتر شناختهشده این دیتابیس محسوب میشود.
PostgreSQL برای انواع مختلف داده، Range Typeهای آمادهای دارد؛ مانند:
daterange
tsrange
tstzrange
int4range
int8range
numrange
خیلی از ما این مدل را استفاده میکنیم:
start_at TIMESTAMP, end_at TIMESTAMP
اما PostgreSQL نوع دادهای دارد که دقیقاً برای همین سناریو طراحی شده است:
period TSTZRANGE
شاید در نگاه اول فقط یک ستون کمتر به نظر برسد، اما مزایای آن بسیار فراتر از این است.
با دو ستون معمولاً باید این شرط را بنویسید:
WHERE start_at < :new_end AND end_at > :new_start
اما با tstzrange:
WHERE period && tstzrange(:new_start, :new_end)
اپراتور && یعنی:
آیا این دو بازه با هم همپوشانی دارند؟
هم خواناتر است و هم احتمال خطای منطقی کمتر میشود.
اگر جدول شما میلیونها رکورد داشته باشد (مثل رزروها، کمپینها یا قیمتها)، میتوانید از GiST Index استفاده کنید:
CREATE INDEX idx_period ON reservations USING GIST(period);
از این به بعد کوئریهایی مثل:
WHERE period && tstzrange(...)
با استفاده از ایندکس اجرا میشوند و عملکرد بسیار بهتری نسبت به شرطهای پیچیده روی دو ستون خواهند داشت.
فرض کنید هیچ دو رزروی برای یک اتاق نباید روی هم بیفتند.
با دو ستون معمولاً باید این منطق را در لایه Application پیادهسازی کنید.
اما PostgreSQL خودش این کار را انجام میدهد:
ALTER TABLE reservations ADD CONSTRAINT no_overlap EXCLUDE USING gist ( room_id WITH =, period WITH && );
از این لحظه، اگر کسی بخواهد یک رزرو متداخل ثبت کند، خود دیتابیس جلوی آن را میگیرد.
Range Types مجموعهای از عملگرهای بسیار کاربردی دارد:
period @> now()
آیا این بازه، زمان فعلی را شامل میشود؟
period <@ other_period
آیا این بازه داخل بازه دیگری قرار دارد؟
lower(period) upper(period)
دریافت شروع و پایان بازه.
اگر با دادههایی مثل این سروکار دارید:
✅ رزرو
✅ شیفت کاری
✅ اعتبار قیمت
✅ کمپینهای تخفیف
✅ بازه ارسال
✅ هر چیزی که مفهوم «از ... تا ...» دارد
به نظرم daterange، tsrange یا tstzrange ارزش بررسی جدی دارند.
گاهی قابلیتهایی که سالهاست در PostgreSQL وجود دارند، بیشترین تأثیر را روی کیفیت طراحی دیتابیس، خوانایی کوئریها و عملکرد سیستم میگذارند.
شما از Range Types در پروژههایتان استفاده کردهاید؟ تجربهتان چه بوده است؟
#PostgreSQL #Database #SQL #Backend #SoftwareEngineering #Performance