8.17. ÐиапазоннÑе ÑипÑ
- 8.17.1. ÐÑÑÑоеннÑе диапазоннÑе ÑипÑ
- 8.17.2. ÐÑимеÑÑ
- 8.17.3. ÐклÑÑение и иÑклÑÑение гÑаниÑ
- 8.17.4. ÐеогÑаниÑеннÑе (беÑконеÑнÑе) диапазонÑ
- 8.17.5. Ðвод-вÑвод диапазонов
- 8.17.6. ÐонÑÑÑÑиÑование диапазонов
- 8.17.7. Ð¢Ð¸Ð¿Ñ Ð´Ð¸ÑкÑеÑнÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¾Ð²
- 8.17.8. ÐпÑеделение новÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½ÑÑ Ñипов
- 8.17.9. ÐндекÑаÑиÑ
- 8.17.10. ÐгÑаниÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¾Ð²
- 8.17.2. ÐÑимеÑÑ
ÐиапазоннÑе ÑÐ¸Ð¿Ñ Ð¿ÑедÑÑавлÑÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð·Ð½Ð°Ñений некоÑоÑого Ñипа даннÑÑ
(он Ñакже назÑваеÑÑÑ Ð¿Ð¾Ð´Ñипом диапазона). ÐапÑимеÑ, диапазон Ñипа timestamp Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедÑÑавлÑÑÑ Ð²Ñеменной инÑеÑвал, когда заÑезеÑвиÑован зал заÑеданий. Рданном ÑлÑÑае Ñипом даннÑÑ
бÑÐ´ÐµÑ tsrange (ÑокÑаÑение Ð¾Ñ Â«timestamp range»), а подÑипом â timestamp. ÐодÑип должен бÑÑÑ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ ÑпоÑÑдоÑиваемÑм, ÑÑÐ¾Ð±Ñ Ð¼Ð¾Ð¶Ð½Ð¾ бÑло однознаÑно опÑеделиÑÑ, где наÑ
одиÑÑÑ Ð·Ð½Ð°Ñение по оÑноÑÐµÐ½Ð¸Ñ Ðº диапазонÑ: внÑÑÑи, до или поÑле него.
ÐиапазоннÑе ÑÐ¸Ð¿Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ñем, ÑÑо позволÑÑÑ Ð¿ÑедÑÑавиÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво возможнÑÑ Ð·Ð½Ð°Ñений в одной ÑÑÑÑкÑÑÑе даннÑÑ Ð¸ ÑÑÑко вÑÑазиÑÑ Ñакие понÑÑиÑ, как пеÑеÑеÑение диапазонов. Ðаиболее оÑевиднÑй ваÑÐ¸Ð°Ð½Ñ Ð¸Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ â пÑименÑÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð´Ð°ÑÑ Ð¸ вÑемени Ð´Ð»Ñ ÑоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑаÑпиÑаниÑ, но Ñакже полезнÑми могÑÑ Ð¾ÐºÐ°Ð·Ð°ÑÑÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ Ñен, инÑеÑÐ²Ð°Ð»Ñ Ð¸Ð·Ð¼ÐµÑений и Ñ. д.
8.17.1. ÐÑÑÑоеннÑе диапазоннÑе ÑипÑ
Postgres Pro Ð¸Ð¼ÐµÐµÑ ÑледÑÑÑие вÑÑÑоеннÑе диапазоннÑе ÑипÑ:
int4rangeâ диапазон подÑипаintegerint8rangeâ диапазон подÑипаbigintnumrangeâ диапазон подÑипаnumerictsrangeâ диапазон подÑипаtimestamp without time zonetstzrangeâ диапазон подÑипаtimestamp with time zonedaterangeâ диапазон подÑипаdate
Ðомимо ÑÑого, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе опÑеделÑÑÑ ÑобÑÑвеннÑе ÑипÑ; подÑобнее ÑÑо опиÑано в CREATE TYPE.
8.17.2. ÐÑимеÑÑ
CREATE TABLE reservation (room int, during tsrange);
INSERT INTO reservation VALUES
(1108, '[2010-01-01 14:30, 2010-01-01 15:30)');
-- ÐÑ
ождение
SELECT int4range(10, 20) @> 3;
-- ÐеÑекÑÑÑие
SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0);
-- ÐолÑÑение веÑÑ
ней гÑаниÑÑ
SELECT upper(int8range(15, 25));
-- ÐÑÑиÑление пеÑеÑеÑениÑ
SELECT int4range(10, 20) * int4range(15, 25);
-- ЯвлÑеÑÑÑ Ð»Ð¸ диапазон пÑÑÑÑм?
SELECT isempty(numrange(1, 5));ÐолнÑй ÑпиÑок опеÑаÑоÑов и ÑÑнкÑий, пÑедназнаÑеннÑÑ Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½ÑÑ Ñипов, пÑиведÑн в ТаблиÑе 9.53 и ТаблиÑе 9.54.
8.17.3. ÐклÑÑение и иÑклÑÑение гÑаниÑ
ÐÑбой непÑÑÑой диапазон Ð¸Ð¼ÐµÐµÑ Ð´Ð²Ðµ гÑаниÑÑ, веÑÑ Ð½ÑÑ Ð¸ нижнÑÑ, и вклÑÑÐ°ÐµÑ Ð²Ñе ÑоÑки Ð¼ÐµÐ¶Ð´Ñ ÑÑими знаÑениÑми. Рнего Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð²Ñ Ð¾Ð´Ð¸ÑÑ ÑоÑка, лежаÑÐ°Ñ Ð½Ð° гÑаниÑе, еÑли диапазон вклÑÑÐ°ÐµÑ ÑÑÑ Ð³ÑаниÑÑ. РнаобоÑоÑ, еÑли диапазон не вклÑÑÐ°ÐµÑ Ð³ÑаниÑÑ, ÑÑиÑаеÑÑÑ, ÑÑо ÑоÑка, лежаÑÐ°Ñ Ð½Ð° ÑÑой гÑаниÑе, в него не Ð²Ñ Ð¾Ð´Ð¸Ñ.
Ð ÑекÑÑовой запиÑи диапазона вклÑÑение нижней гÑаниÑÑ Ð¾Ð±Ð¾Ð·Ð½Ð°ÑаеÑÑÑ Ñимволом «[», а иÑклÑÑением â Ñимволом «(». ÐÐ»Ñ Ð²ÐµÑÑ
ней гÑаниÑÑ Ð²ÐºÐ»ÑÑение обознаÑаеÑÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸Ñно, Ñимволом «]», а иÑклÑÑение â Ñимволом «)». (ÐодÑобнее ÑÑо опиÑано в ÐодÑазделе 8.17.5.)
ÐÐ»Ñ Ð¿ÑовеÑки, вклÑÑаеÑÑÑ Ð»Ð¸ нижнÑÑ Ð¸Ð»Ð¸ веÑÑ
нÑÑ Ð³ÑаниÑа в диапазон, пÑедназнаÑÐµÐ½Ñ ÑÑнкÑии lower_inc и upper_inc, ÑооÑвеÑÑÑвенно.
8.17.4. ÐеогÑаниÑеннÑе (беÑконеÑнÑе) диапазонÑ
ÐижнÑÑ Ð³ÑаниÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° можно опÑÑÑиÑÑ Ð¸ опÑеделиÑÑ Ñем ÑамÑм диапазон, вклÑÑаÑÑий вÑе знаÑениÑ, лежаÑие ниже веÑÑ
ней гÑаниÑÑ, напÑимеÑ: (,3]. ÐодобнÑм обÑазом, еÑли не опÑеделиÑÑ Ð²ÐµÑÑ
нÑÑ Ð³ÑаниÑÑ, в диапазон войдÑÑ Ð²Ñе знаÑениÑ, лежаÑие вÑÑе нижней гÑаниÑÑ. ÐÑли же опÑÑена и нижнÑÑ, и веÑÑ
нÑÑ Ð³ÑаниÑÑ, Ñакой диапазон бÑÐ´ÐµÑ Ð²ÐºÐ»ÑÑаÑÑ Ð²Ñе возможнÑе знаÑÐµÐ½Ð¸Ñ Ñвоего подÑипа. Указание оÑÑÑÑÑÑвÑÑÑей гÑаниÑÑ ÐºÐ°Ðº вклÑÑаемой в диапазон авÑомаÑиÑеÑки пÑеобÑазÑеÑÑÑ Ð² иÑклÑÑаÑÑее; напÑимеÑ, [,] пÑеобÑазÑеÑÑÑ Ð² (,). Ðожно воÑпÑинимаÑÑ Ð¾ÑÑÑÑÑÑвÑÑÑие знаÑÐµÐ½Ð¸Ñ ÐºÐ°Ðº плÑÑ/минÑÑ Ð±ÐµÑконеÑноÑÑÑ, но вÑÑ Ð¶Ðµ ÑÑо оÑобÑе знаÑÐµÐ½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½Ð¾Ð³Ð¾ Ñипа, коÑоÑÑе оÑ
ваÑÑваÑÑ Ð¸ возможнÑе Ð´Ð»Ñ Ð¿Ð¾Ð´Ñипа знаÑÐµÐ½Ð¸Ñ Ð¿Ð»ÑÑ/минÑÑ Ð±ÐµÑконеÑноÑÑÑ.
ÐÐ»Ñ Ð¿Ð¾Ð´Ñипов, в коÑоÑÑÑ
еÑÑÑ Ð¿Ð¾Ð½ÑÑие «беÑконеÑноÑÑÑ», infinity Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð² каÑеÑÑве Ñвного знаÑÐµÐ½Ð¸Ñ Ð³ÑаниÑÑ. ÐÑи ÑÑом, напÑимеÑ, в диапазон [today,infinity) Ñ Ð¿Ð¾Ð´Ñипом timestamp не бÑÐ´ÐµÑ Ð²Ñ
одиÑÑ ÑпеÑиалÑное знаÑение infinity данного подÑипа, однако ÑÑо знаÑение бÑÐ´ÐµÑ Ð²Ñ
одиÑÑ Ð² диапазон [today,infinity], как и в Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ [today,) и [today,].
ÐÑовеÑиÑÑ, опÑеделена ли веÑÑ
нÑÑ Ð¸Ð»Ð¸ нижнÑÑ Ð³ÑаниÑа, можно Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑнкÑий lower_inf и upper_inf, ÑооÑвеÑÑÑвенно.
8.17.5. Ðвод-вÑвод диапазонов
Ðводимое знаÑение диапазона должно запиÑÑваÑÑÑÑ Ð² одной из ÑледÑÑÑÐ¸Ñ ÑоÑм:
(нижнÑÑ-гÑаниÑа,веÑÑ Ð½ÑÑ-гÑаниÑа) (нижнÑÑ-гÑаниÑа,веÑÑ Ð½ÑÑ-гÑаниÑа] [нижнÑÑ-гÑаниÑа,веÑÑ Ð½ÑÑ-гÑаниÑа) [нижнÑÑ-гÑаниÑа,веÑÑ Ð½ÑÑ-гÑаниÑа] empty
Тип Ñкобок (квадÑаÑнÑе или кÑÑглÑе) опÑеделÑеÑ, вклÑÑаÑÑÑÑ Ð»Ð¸ в диапазон ÑооÑвеÑÑÑвÑÑÑие гÑаниÑÑ, как опиÑано вÑÑе. ÐамеÑÑÑе, ÑÑо поÑледнÑÑ ÑоÑма ÑодеÑÐ¶Ð¸Ñ ÑолÑко Ñлово empty и опÑеделÑÐµÑ Ð¿ÑÑÑой диапазон (диапазон, не ÑодеÑжаÑий ÑоÑек).
ÐдеÑÑ Ð½Ð¸Ð¶Ð½ÑÑ-гÑаниÑа Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑÑокой Ñ Ð´Ð¾Ð¿ÑÑÑимÑм знаÑением подÑипа или бÑÑÑ Ð¿ÑÑÑой (Ñогда диапазон бÑÐ´ÐµÑ Ð±ÐµÐ· нижней гÑаниÑÑ). ÐналогиÑно, веÑÑ
нÑÑ-гÑаниÑа Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑÑÑ Ð¾Ð´Ð½Ð¸Ð¼ из знаÑений подÑипа или бÑÑÑ Ð½ÐµÐ¾Ð¿ÑеделÑнной (пÑÑÑой).
ÐÑбое знаÑение гÑаниÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° можно заклÑÑиÑÑ Ð² кавÑÑки ("). РеÑли знаÑение ÑодеÑÐ¶Ð¸Ñ ÐºÑÑглÑе или квадÑаÑнÑе Ñкобки, запÑÑÑе, кавÑÑки или обÑаÑнÑÑ ÐºÐ¾ÑÑÑ ÑеÑÑÑ, иÑполÑзоваÑÑ ÐºÐ°Ð²ÑÑки необÑ
одимо, ÑÑÐ¾Ð±Ñ ÑÑи ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ Ð½Ðµ ÑаÑÑмаÑÑивалиÑÑ ÐºÐ°Ðº ÑаÑÑÑ ÑинÑакÑиÑа диапазона. ЧÑÐ¾Ð±Ñ Ð²ÐºÐ»ÑÑиÑÑ Ð² знаÑение гÑаниÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð°, заклÑÑÑнное в кавÑÑки, Ñакие ÑимволÑ, как кавÑÑки или обÑаÑÐ½Ð°Ñ ÐºÐ¾ÑÐ°Ñ ÑеÑÑа, пеÑед ними нÑжно добавиÑÑ Ð¾Ð±ÑаÑнÑÑ ÐºÐ¾ÑÑÑ ÑеÑÑÑ. (ÐÑоме Ñого, пÑодÑблиÑованнÑе кавÑÑки в знаÑении диапазона, заклÑÑÑнного в кавÑÑки, воÑпÑинимаÑÑÑÑ ÐºÐ°Ðº одинаÑнÑе, подобно апоÑÑÑоÑам в ÑÑÑокаÑ
SQL.) С дÑÑгой ÑÑоÑонÑ, можно обойÑиÑÑ Ð±ÐµÐ· кавÑÑек, заÑиÑив вÑе ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ Ð² даннÑÑ
, коÑоÑÑе могÑÑ Ð±ÑÑÑ Ð²Ð¾ÑпÑинÑÑÑ ÐºÐ°Ðº ÑаÑÑÑ ÑинÑакÑиÑа диапазона, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑпеÑпоÑледоваÑелÑноÑÑей. ЧÑÐ¾Ð±Ñ Ð·Ð°Ð´Ð°ÑÑ Ð² каÑеÑÑве гÑаниÑÑ Ð¿ÑÑÑÑÑ ÑÑÑокÑ, нÑжно ввеÑÑи "", Ñак как пÑÑÑÐ°Ñ ÑÑÑока без кавÑÑек бÑÐ´ÐµÑ Ð¾Ð·Ð½Ð°ÑаÑÑ Ð¾ÑÑÑÑÑÑвие гÑаниÑÑ.
ÐÑобелÑнÑе ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ Ð´Ð¾ и поÑле опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° игноÑиÑÑÑÑÑÑ, но когда они пÑиÑÑÑÑÑвÑÑÑ Ð²Ð½ÑÑÑи Ñкобок, они воÑпÑинимаÑÑÑÑ ÐºÐ°Ðº ÑаÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð²ÐµÑÑ Ð½ÐµÐ¹ или нижней гÑаниÑÑ. (ХоÑÑ Ð¾Ð½Ð¸ могÑÑ Ñакже игноÑиÑоваÑÑÑÑ Ð² завиÑимоÑÑи Ð¾Ñ Ð¿Ð¾Ð´Ñипа диапазона.)
ÐÑимеÑание
ÐÑи пÑавила оÑÐµÐ½Ñ Ð¿Ð¾Ñ Ð¾Ð¶Ð¸ на пÑавила запиÑи знаÑений Ð´Ð»Ñ Ð¿Ð¾Ð»ÐµÐ¹ ÑоÑÑавнÑÑ Ñипов. ÐополниÑелÑнÑе замеÑÐ°Ð½Ð¸Ñ Ð¿ÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ð² ÐодÑазделе 8.16.6.
ÐÑимеÑÑ:
-- в диапазон вклÑÑаеÑÑÑ 3, не вклÑÑаеÑÑÑ 7 и вклÑÑаÑÑÑÑ Ð²Ñе ÑоÑки Ð¼ÐµÐ¶Ð´Ñ Ð½Ð¸Ð¼Ð¸ SELECT '[3,7)'::int4range; -- в диапазон не вклÑÑаÑÑÑÑ 3 и 7, но вклÑÑаÑÑÑÑ Ð²Ñе ÑоÑки Ð¼ÐµÐ¶Ð´Ñ Ð½Ð¸Ð¼Ð¸ SELECT '(3,7)'::int4range; -- в диапазон вклÑÑаеÑÑÑ ÑолÑко одно знаÑение 4 SELECT '[4,4]'::int4range; -- диапазон не вклÑÑÐ°ÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ñ ÑоÑек (ноÑмализаÑÐ¸Ñ Ð·Ð°Ð¼ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ опÑеделение на 'empty') SELECT '[4,4)'::int4range;
8.17.6. ÐонÑÑÑÑиÑование диапазонов
ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ диапазонного Ñипа опÑеделена ÑÑнкÑÐ¸Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑа, имеÑÑÐ°Ñ Ñо же имÑ, ÑÑо и даннÑй Ñип. ÐÑполÑзоваÑÑ ÑÑÐ¾Ñ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¾Ñ Ð¾Ð±ÑÑно Ñдобнее, Ñем запиÑÑваÑÑ ÑекÑÑовÑÑ ÐºÐ¾Ð½ÑÑанÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð°, Ñак как ÑÑо избавлÑÐµÑ Ð¾Ñ Ð¿Ð¾ÑÑебноÑÑи в дополниÑелÑнÑÑ
кавÑÑкаÑ
. ФÑнкÑÐ¸Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑа Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑинимаÑÑ Ð´Ð²Ð° или ÑÑи паÑамеÑÑа. ÐаÑÐ¸Ð°Ð½Ñ Ñ Ð´Ð²ÑÐ¼Ñ Ð¿Ð°ÑамеÑÑами ÑоздаÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ в ÑÑандаÑÑной ÑоÑме (нижнÑÑ Ð³ÑаниÑа вклÑÑаеÑÑÑ, веÑÑ
нÑÑ Ð¸ÑклÑÑаеÑÑÑ), Ñогда как Ð´Ð»Ñ Ð²Ð°ÑианÑа Ñ ÑÑÐµÐ¼Ñ Ð¿Ð°ÑамеÑÑами вклÑÑение гÑÐ°Ð½Ð¸Ñ Ð¾Ð¿ÑеделÑеÑÑÑ ÑÑеÑÑим паÑамеÑÑом. ТÑеÑий паÑамеÑÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ ÑодеÑжаÑÑ Ð¾Ð´Ð½Ñ Ð¸Ð· ÑÑÑок: «()», «(]», «[)» или «[]». ÐапÑимеÑ:
-- ÐÐ¾Ð»Ð½Ð°Ñ ÑоÑма: нижнÑÑ Ð³ÑаниÑа, веÑÑ Ð½ÑÑ Ð³ÑаниÑа и ÑекÑÑÐ¾Ð²Ð°Ñ ÑÑÑока, опÑеделÑÑÑÐ°Ñ -- вклÑÑение/иÑклÑÑение гÑаниÑ. SELECT numrange(1.0, 14.0, '(]'); -- ÐÑли ÑÑеÑий аÑгÑÐ¼ÐµÐ½Ñ Ð¾Ð¿ÑÑен, подÑазÑмеваеÑÑÑ '[)'. SELECT numrange(1.0, 14.0); -- ХоÑÑ Ð·Ð´ÐµÑÑ ÑказÑваеÑÑÑ '(]', пÑи вÑводе знаÑение бÑÐ´ÐµÑ Ð¿Ñиведено к -- канониÑеÑÐºÐ¾Ð¼Ñ Ð²Ð¸Ð´Ñ, Ñак как int8range â Ñип диÑкÑеÑного диапазона (Ñм. ниже). SELECT int8range(1, 14, '(]'); -- Ðогда вмеÑÑо лÑбой гÑаниÑÑ ÑказÑваеÑÑÑ NULL, ÑооÑвеÑÑÑвÑÑÑей гÑаниÑÑ Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° не бÑдеÑ. SELECT numrange(NULL, 2.2);
8.17.7. Ð¢Ð¸Ð¿Ñ Ð´Ð¸ÑкÑеÑнÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¾Ð²
ÐиÑкÑеÑнÑм диапазоном ÑÑиÑаеÑÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½, Ð´Ð»Ñ Ð¿Ð¾Ð´Ñипа коÑоÑого однознаÑно опÑеделÑн «Ñаг», как, напÑимеÑ, Ð´Ð»Ñ Ñипов integer и date. ÐнаÑÐµÐ½Ð¸Ñ ÑÑиÑ
двÑÑ
Ñипов можно назваÑÑ ÑоÑедними, когда Ð¼ÐµÐ¶Ð´Ñ Ð½Ð¸Ð¼Ð¸ Ð½ÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ñ
дÑÑгиÑ
знаÑений. РнепÑеÑÑвнÑÑ
диапазонаÑ
, напÑоÑив, вÑегда (или поÑÑи вÑегда) можно найÑи еÑÑ Ð¾Ð´Ð½Ð¾ знаÑение Ð¼ÐµÐ¶Ð´Ñ Ð´Ð²ÑÐ¼Ñ Ð´Ð°Ð½Ð½Ñми. ÐапÑимеÑ, непÑеÑÑвнÑм диапазоном бÑÐ´ÐµÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ñ Ð¿Ð¾Ð´Ñипами numeric и timestamp. (ХоÑÑ timestamp Ð¸Ð¼ÐµÐµÑ Ð¾Ð³ÑаниÑеннÑÑ ÑоÑноÑÑÑ, Ñо еÑÑÑ ÑеоÑеÑиÑеÑки он ÑвлÑеÑÑÑ Ð´Ð¸ÑкÑеÑнÑм, но вÑÑ Ð¶Ðµ лÑÑÑе ÑÑиÑаÑÑ ÐµÐ³Ð¾ непÑеÑÑвнÑм, Ñак как Ñаг его обÑÑно не опÑеделÑн.)
Ðожно Ñакже ÑÑиÑаÑÑ Ð´Ð¸ÑкÑеÑнÑм подÑип диапазона, в коÑоÑом ÑÑÑко опÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ð¿Ð¾Ð½ÑÑÐ¸Ñ Â«ÑледÑÑÑего» и «пÑедÑдÑÑего» ÑлеменÑа Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ знаÑениÑ. Такие опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ Ð¿ÑеобÑазовÑваÑÑ Ð³ÑаниÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° из вклÑÑаемÑÑ
в иÑклÑÑаемÑе, вÑбиÑÐ°Ñ ÑледÑÑÑий или пÑедÑдÑÑий ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð²Ð¼ÐµÑÑо заданного знаÑениÑ. ÐапÑимеÑ, Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ ÑелоÑиÑленного Ñипа [4,8] и (3,9) опиÑÑваÑÑ Ð¾Ð´Ð½Ð¾ и Ñо же множеÑÑво знаÑений; но Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° подÑипа numeric ÑÑо не Ñак.
ÐÐ»Ñ Ñипа диÑкÑеÑного диапазона опÑеделÑеÑÑÑ ÑÑнкÑÐ¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ð·Ð°Ñии, ÑÑиÑÑваÑÑÐ°Ñ ÑÐ°Ð·Ð¼ÐµÑ Ñага Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ подÑипа. ÐадаÑа ÑÑой ÑÑнкÑии â пÑеобÑазоваÑÑ ÑавнознаÑнÑе Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ Ðº единÑÑÐ²ÐµÐ½Ð½Ð¾Ð¼Ñ Ð¿ÑедÑÑавлениÑ, в ÑаÑÑноÑÑи ноÑмализоваÑÑ Ð²ÐºÐ»ÑÑаемÑе и иÑклÑÑаемÑе гÑаниÑÑ. ÐÑли ÑÑнкÑÐ¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ð·Ð°Ñии не опÑеделена, Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ Ñ ÑазлиÑнÑм опÑеделением бÑдÑÑ Ð²Ñегда ÑÑиÑаÑÑÑÑ ÑазнÑми, даже когда они на Ñамом деле пÑедÑÑавлÑÑÑ Ð¾Ð´Ð½Ð¾ множеÑÑво знаÑений.
ÐÐ»Ñ Ð²ÑÑÑоеннÑÑ
Ñипов int4range, int8range и daterange канониÑеÑкое пÑедÑÑавление вклÑÑÐ°ÐµÑ Ð½Ð¸Ð¶Ð½ÑÑ Ð³ÑаниÑÑ Ð¸ не вклÑÑÐ°ÐµÑ Ð²ÐµÑÑ
нÑÑ; Ñо еÑÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ пÑиводиÑÑÑ Ðº Ð²Ð¸Ð´Ñ [). Ðднако Ð´Ð»Ñ Ð½ÐµÑÑандаÑÑнÑÑ
Ñипов можно иÑполÑзоваÑÑ Ð¸ дÑÑгие ÑоглаÑениÑ.
8.17.8. ÐпÑеделение новÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½ÑÑ Ñипов
ÐолÑзоваÑели могÑÑ Ð¾Ð¿ÑеделÑÑÑ ÑобÑÑвеннÑе диапазоннÑе ÑипÑ. ÐÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾, когда нÑжно иÑполÑзоваÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ Ñ Ð¿Ð¾Ð´Ñипами, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
Ð½ÐµÑ Ð²ÑÑÑоеннÑÑ
диапазоннÑÑ
Ñипов. ÐапÑимеÑ, можно опÑеделиÑÑ Ð½Ð¾Ð²Ñй Ñип диапазона Ð´Ð»Ñ Ð¿Ð¾Ð´Ñипа float8:
CREATE TYPE floatrange AS RANGE (
subtype = float8,
subtype_diff = float8mi
);
SELECT '[1.234, 5.678]'::floatrange; Так как Ð´Ð»Ñ float8 оÑмÑÑленное знаÑение «Ñага» не опÑеделено, ÑÑнкÑÐ¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ð·Ð°Ñии в данном пÑимеÑе не задаÑÑÑÑ.
ÐпÑеделÑÑ ÑобÑÑвеннÑй диапазоннÑй Ñип, Ð²Ñ Ñакже можеÑе вÑбÑаÑÑ Ð´ÑÑгие пÑавила ÑоÑÑиÑовки или клаÑÑ Ð¾Ð¿ÐµÑаÑоÑа B-деÑева Ð´Ð»Ñ ÐµÐ³Ð¾ подÑипа, ÑÑо Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ Ð¿Ð¾ÑÑдок знаÑений, Ð¾Ñ ÐºÐ¾ÑоÑого завиÑиÑ, какие знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÑÑ Ð² заданнÑй диапазон.
ÐÑли подÑип можно ÑаÑÑмаÑÑиваÑÑ ÐºÐ°Ðº диÑкÑеÑнÑй, а не непÑеÑÑвнÑй, в команде CREATE TYPE ÑледÑÐµÑ Ñакже задаÑÑ ÑÑнкÑÐ¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ð·Ð°Ñии. ÐÑой ÑÑнкÑии бÑÐ´ÐµÑ Ð¿ÐµÑедаваÑÑÑÑ Ð·Ð½Ð°Ñение диапазона, а она должна веÑнÑÑÑ ÑавнознаÑное знаÑение, но, возможно, Ñ Ð´ÑÑгими гÑаниÑами и ÑоÑмаÑиÑованием. ÐÐ»Ñ Ð´Ð²ÑÑ
диапазонов, пÑедÑÑавлÑÑÑиÑ
одно множеÑÑво знаÑений, напÑимеÑ, ÑелоÑиÑленнÑе Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ [1, 7] и [1, 8), ÑÑнкÑÐ¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ð·Ð°Ñии должна вÑдаваÑÑ Ð¾Ð´Ð¸Ð½ ÑезÑлÑÑаÑ. Ðакое именно пÑедÑÑавление бÑÐ´ÐµÑ ÑÑиÑаÑÑÑÑ ÐºÐ°Ð½Ð¾Ð½Ð¸ÑеÑким, не Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ â главное, ÑÑÐ¾Ð±Ñ Ð´Ð²Ð° ÑавнознаÑнÑÑ
диапазона, оÑÑоÑмаÑиÑованнÑÑ
по-ÑазномÑ, вÑегда пÑеобÑазовÑвалиÑÑ Ð² одно знаÑение Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñм ÑоÑмаÑиÑованием. Ðомимо иÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑоÑмаÑа вклÑÑаемÑÑ
/иÑклÑÑаемÑÑ
гÑаниÑ, ÑÑнкÑÐ¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ð·Ð°Ñии Ð¼Ð¾Ð¶ÐµÑ Ð¾ÐºÑÑглÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð³ÑаниÑ, еÑли ÑÐ°Ð·Ð¼ÐµÑ Ñага пÑевÑÑÐ°ÐµÑ ÑоÑноÑÑÑ Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñипа. ÐапÑимеÑ, в Ñипе диапазона Ð´Ð»Ñ Ð¿Ð¾Ð´Ñипа timestamp можно опÑеделиÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ñага, ÑавнÑй ÑаÑÑ, Ñогда ÑÑнкÑÐ¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ð·Ð°Ñии должна бÑÐ´ÐµÑ Ð¾ÐºÑÑглиÑÑ Ð³ÑаниÑÑ, заданнÑе, напÑÐ¸Ð¼ÐµÑ Ñ ÑоÑноÑÑÑÑ Ð´Ð¾ минÑÑ, либо вмеÑÑо ÑÑого вÑдаÑÑ Ð¾ÑибкÑ.
Ðомимо ÑÑого, Ð´Ð»Ñ Ð»Ñбого диапазонного Ñипа, оÑиенÑиÑованного на иÑполÑзование Ñ Ð¸Ð½Ð´ÐµÐºÑами GiST или SP-GiST, должна бÑÑÑ Ð¾Ð¿Ñеделена ÑазниÑа знаÑений подÑипов, ÑÑнкÑÐ¸Ñ subtype_diff. (ÐÐ½Ð´ÐµÐºÑ ÑÐ¼Ð¾Ð¶ÐµÑ ÑабоÑаÑÑ Ð¸ без subtype_diff, но в болÑÑинÑÑве ÑлÑÑаев ÑÑо бÑÐ´ÐµÑ Ð½Ðµ Ñак ÑÑÑекÑивно.) ÐÑа ÑÑнкÑÐ¸Ñ Ð¿ÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð½Ð° вÑ
од два знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñипа и возвÑаÑÐ°ÐµÑ Ð¸Ñ
ÑазниÑÑ (Ñ. е. X минÑÑ Y) в знаÑении Ñипа float8. Рпоказанном вÑÑе пÑимеÑе Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ ÑÑнкÑÐ¸Ñ float8mi, опÑеделÑÑÑÐ°Ñ Ð½Ð¸Ð¶ÐµÐ»ÐµÐ¶Ð°ÑÑÑ ÑеализаÑÐ¸Ñ Ð¾Ð±ÑÑного опеÑаÑоÑа «минÑÑ» Ð´Ð»Ñ Ñипа float8, но Ð´Ð»Ñ Ð´ÑÑгого подÑипа могÑÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе пÑеобÑазованиÑ. Ðногда Ð´Ð»Ñ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑазниÑÑ Ð² ÑиÑловом виде ÑÑебÑеÑÑÑ ÐµÑÑ Ð¸ ÑвоÑÑеÑкий подÑ
од. ФÑнкÑÐ¸Ñ subtype_diff, наÑколÑко ÑÑо возможно, должна бÑÑÑ ÑоглаÑована Ñ Ð¿Ð¾ÑÑдком ÑоÑÑиÑовки, вÑÑекаÑÑим из вÑбÑаннÑÑ
пÑавил ÑоÑÑиÑовки и клаÑÑа опеÑаÑоÑа; Ñо еÑÑÑ, ÐµÑ ÑезÑлÑÑÐ°Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ Ð¿Ð¾Ð»Ð¾Ð¶Ð¸ÑелÑнÑм, еÑли ÑоглаÑно поÑÑÐ´ÐºÑ ÑоÑÑиÑовки пеÑвÑй ÐµÑ Ð°ÑгÑÐ¼ÐµÐ½Ñ Ð±Ð¾Ð»ÑÑе вÑоÑого.
ÐÑÑ Ð¾Ð´Ð¸Ð½, не ÑÑÐ¾Ð»Ñ ÑÑивиалÑнÑй пÑÐ¸Ð¼ÐµÑ ÑÑнкÑии subtype_diff:
CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS
'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;
CREATE TYPE timerange AS RANGE (
subtype = time,
subtype_diff = time_subtype_diff
);
SELECT '[11:10, 23:00]'::timerange;ÐополниÑелÑнÑе ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ Ñоздании диапазоннÑÑ Ñипов можно найÑи в опиÑании CREATE TYPE.
8.17.9. ÐндекÑаÑиÑ
ÐÐ»Ñ ÑÑолбÑов, имеÑÑÐ¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½Ñй Ñип, можно ÑоздаÑÑ Ð¸Ð½Ð´ÐµÐºÑÑ GiST и SP-GiST. ÐапÑимеÑ, Ñак ÑоздаÑÑÑÑ Ð¸Ð½Ð´ÐµÐºÑ GiST:
CREATE INDEX reservation_idx ON reservation USING GIST (during);
ÐÐ½Ð´ÐµÐºÑ GiST или SP-GiST Ð¿Ð¾Ð¼Ð¾Ð³Ð°ÐµÑ ÑÑкоÑиÑÑ Ð·Ð°Ð¿ÑоÑÑ Ñо ÑледÑÑÑими опеÑаÑоÑами: =, &&, <@, @>, <<, >>, -|-, &< и &> (дополниÑелÑно о ниÑ
можно ÑзнаÑÑ Ð² ТаблиÑе 9.53.
ÐÑоме Ñого, Ð´Ð»Ñ ÑакиÑ
ÑÑолбÑов можно ÑоздаÑÑ Ð¸Ð½Ð´ÐµÐºÑÑ Ð½Ð° оÑнове Ñ
еÑа и B-деÑевÑев. ÐÐ»Ñ Ð¸Ð½Ð´ÐµÐºÑов ÑакиÑ
Ñипов полезен по ÑÑÑи ÑолÑко один опеÑаÑÐ¾Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° â Ñавно. ÐоÑÑдок ÑоÑÑиÑовки B-деÑева опÑеделÑеÑÑÑ Ð´Ð»Ñ Ð·Ð½Ð°Ñений диапазона ÑооÑвеÑÑÑвÑÑÑими опеÑаÑоÑами < и >, но ÑÑÐ¾Ñ Ð¿Ð¾ÑÑдок Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑоизволÑнÑм и он не оÑÐµÐ½Ñ Ð²Ð°Ð¶ÐµÐ½ в ÑеалÑном миÑе. ÐоддеÑжка B-деÑевÑев и Ñ
еÑей диапазоннÑми Ñипами нÑжна в оÑновном Ð´Ð»Ñ ÑоÑÑиÑовки и Ñ
еÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñи вÑполнении запÑоÑов, но не Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑамиÑ
индекÑов.
8.17.10. ÐгÑаниÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¾Ð²
Тогда как Ð´Ð»Ñ ÑкалÑÑнÑÑ
знаÑений еÑÑеÑÑвеннÑм огÑаниÑением ÑвлÑеÑÑÑ UNIQUE, оно обÑÑно не подÑ
Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½ÑÑ
Ñипов. ÐмеÑÑо ÑÑого ÑаÑе оказÑваÑÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½ÐµÐµ огÑаниÑениÑ-иÑклÑÑÐµÐ½Ð¸Ñ (Ñм. CREATE TABLE ... CONSTRAINT ... EXCLUDE). Такие огÑаниÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ, напÑÐ¸Ð¼ÐµÑ Ð¾Ð¿ÑеделиÑÑ ÑÑловие «непеÑеÑеÑениÑ» диапазонов. ÐапÑимеÑ:
CREATE TABLE reservation (
during tsrange,
EXCLUDE USING GIST (during WITH &&)
);ÐÑо огÑаниÑение не Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð²Ñеменно ÑÐ¾Ñ ÑаниÑÑ Ð² ÑаблиÑе неÑколÑко диапазонов, коÑоÑÑе накладÑваÑÑÑÑ Ð´ÑÑг на дÑÑга:
INSERT INTO reservation VALUES
('[2010-01-01 11:30, 2010-01-01 15:00)');
INSERT 0 1
INSERT INTO reservation VALUES
('[2010-01-01 14:45, 2010-01-01 15:45)');
ÐШÐÐÐÐ: конÑликÑÑÑÑее знаÑение клÑÑа наÑÑÑÐ°ÐµÑ Ð¾Ð³ÑаниÑение-иÑклÑÑение "reservation_during_excl"
ÐÐÐÐ ÐÐÐÐСТÐ: ÐлÑÑ (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00"))
конÑликÑÑÐµÑ Ñ ÑÑÑеÑÑвÑÑÑим клÑÑом (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")).ÐÐ»Ñ Ð¼Ð°ÐºÑималÑной гибкоÑÑи в огÑаниÑении-иÑклÑÑении можно ÑоÑеÑаÑÑ Ð¿ÑоÑÑÑе ÑкалÑÑнÑе ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ
Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð°Ð¼Ð¸, иÑполÑзÑÑ ÑаÑÑиÑение btree_gist. ÐапÑимеÑ, еÑли btree_gist ÑÑÑановлено, ÑледÑÑÑее огÑаниÑение не бÑÐ´ÐµÑ Ð´Ð¾Ð¿ÑÑкаÑÑ Ð¿ÐµÑеÑекаÑÑиеÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ, ÑолÑко еÑли ÑовпадаÑÑ Ñакже и номеÑа комнаÑ:
CREATE EXTENSION btree_gist;
CREATE TABLE room_reservation (
room text,
during tsrange,
EXCLUDE USING GIST (room WITH =, during WITH &&)
);
INSERT INTO room_reservation VALUES
('123A', '[2010-01-01 14:00, 2010-01-01 15:00)');
INSERT 0 1
INSERT INTO room_reservation VALUES
('123A', '[2010-01-01 14:30, 2010-01-01 15:30)');
ÐШÐÐÐÐ: конÑликÑÑÑÑее знаÑение клÑÑа наÑÑÑÐ°ÐµÑ Ð¾Ð³ÑаниÑение-иÑклÑÑение "room_reservation_room_during_excl"
ÐÐÐÐ ÐÐÐÐСТÐ: ÐлÑÑ (room, during)=(123A, [ 2010-01-01 14:30:00, 2010-01-01 15:30:00 )) конÑликÑÑеÑ
Ñ ÑÑÑеÑÑвÑÑÑим клÑÑом (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")).
INSERT INTO room_reservation VALUES
('123B', '[2010-01-01 14:30, 2010-01-01 15:30)');
INSERT 0 1