1. 程式人生 > >PostgreSQL中的範圍型別

PostgreSQL中的範圍型別

範圍型別是表達某種元素型別的一個值的範圍的資料型別。範圍型別可以表達一種單一範圍值中的多個元素值,並且可以很清晰地表達諸如範圍重疊等概念。本文將對範圍型別進行簡單介紹。

PostgreSQL帶有以下幾種內建範圍型別:

1) int4range (integer範圍)

2) int8range (bigint範圍)

3) numrange (numeric範圍)

4) tsrange (不帶時區的timestamp範圍)

5) tstzrange (帶時區的timestamp範圍)

6) daterange (date範圍)

此外,可以使用自定義的範圍型別。

有邊界的範圍

每一個非空範圍都有兩個界限,下界和上界。這些值之間的所有點都被包括在範圍內。一個包含界限意味著邊界點本身也被包括在範圍內,而一個排除邊界意味著邊界點不被包括在範圍內。

在一個範圍的文字形式中,一個包含下界被表達為“[”而一個排除下界被表達為“(”。同樣,一個包含上界被表達為“]”而一個排除上界被表達為“)”。

函式lower_inc和upper_inc分別測試一個範圍值的上下界。

一個範圍值的輸入必須遵循下列模式之一:

(lower-bound,upper-bound)
(lower-bound,upper-bound]
[lower-bound,upper-bound)
[lower-bound,upper-bound]
empty

無邊界的範圍

一個範圍的下界可以被忽略,這意味著所有小於上界的點都被包括在範圍中。同樣,如果範圍的上界被忽略,那麼所有比上界大的的都被包括在範圍中。如果上下界都被忽略,該元素型別的所有值都被認為在該範圍中。

函式lower_inf和upper_inf分別測試一個範圍的無限上下界。

構建範圍

每一種範圍型別都有一個與其同名的構造器函式。構造器函式接受兩個或三個引數。兩個引數的形式以標準的形式構造一個範圍(下界是包含的,上界是排除的),而三個引數的形式按照第三個引數指定的界限形式構造一個範圍。第三個引數必須是下列字串之一:“()”、 “(]”、 “[)”或者 “[]”。

舉幾個例子來說明構建範圍的方法:

1) 完整的形式:包括下界、上界以及指示界限包含性/排除性的文字引數。

postgres=# select tsrange('2018-10-31 12:00:00','2018-11-11 00:00:00','[]');
                    tsrange                    
-----------------------------------------------
 ["2018-10-31 12:00:00","2018-11-11 00:00:00"]
(1 row)

2) 如果第三個引數被忽略,則預設為“[)”。

postgres=# select numrange(2.5,12.0);
  numrange  
------------
 [2.5,12.0)
(1 row)

3) 為一個界限使用null導致範圍在該邊界是無界的。

postgres=# select numrange(null,3.0);
 numrange 
----------
 (,3.0)
(1 row)

範圍索引

可以為範圍型別的表列建立GiST和SP-GiST索引。一個GiST或SP-GiST索引可以加速涉及以下範圍操作符的查詢:

=
&&
<@
@>
<<
>>
-|-
&<
&>

此外,B-樹和雜湊索引可以在範圍型別的表列上建立。

範圍上的約束

唯一約束通常不適合於範圍型別。作為替代,排除約束是更加適合的方式。例如:

postgres=# create table orders(order_time tsrange,exclude using gist(order_time with &&));
CREATE TABLE

該約束將阻止任何重疊值同時存在於表中,例如:

postgres=# insert into orders values('[2018-10-31 12:00,2018-10-31 17:00)');
INSERT 0 1
postgres=# insert into orders values('[2018-10-31 15:00,2018-10-31 18:00)');
2018-10-31 17:21:37.280 CST [2119] ERROR:  conflicting key value violates exclusion constraint "orders_order_time_excl"
2018-10-31 17:21:37.280 CST [2119] DETAIL:  Key (order_time)=(["2018-10-31 15:00:00","2018-10-31 18:00:00")) conflicts with existing key (order_time)=(["2018-10-31 12:00:00","2018-10-31 17:00:00")).
2018-10-31 17:21:37.280 CST [2119] STATEMENT:  insert into orders values('[2018-10-31 15:00,2018-10-31 18:00)');
ERROR:  conflicting key value violates exclusion constraint "orders_order_time_excl"
DETAIL:  Key (order_time)=(["2018-10-31 15:00:00","2018-10-31 18:00:00")) conflicts with existing key (order_time)=(["2018-10-31 12:00:00","2018-10-31 17:00:00")).

 

By Kalath