不要错过这个伟大的概述PostgreSQL 14 Umair Shahid最近放在一起,PostgreSQL 14 -性能、安全性、可用性和可观察性!
范围的数据类型已经在Postgresql有一段时间了,然而,Postgresql 14,我们看到的引入多量程数据类型。讨论之前,让我们盖的基础到底的巫毒魔法一系列数据类型,以及为什么你会想要使用它之前多量程不同。
数据类型存储一个开始和结束值范围。存储的数据可能是一个整数或一个DateTime(时间戳)。注意:如果您感兴趣的话,您还可以创建自己的自定义类型的范围。为什么你会使用这个吗?我能想到的一些有趣的用例,但是最通用的一个跟踪状态改变和持续时间。例如:
- 这台机器正在从X到Y时间运行。
- 这个房间X和Y之间占领。
- 这个销售/价格是活跃在这些时间框架。
数据已经存储了年龄范围没有特定的“范围”数据类型。让我们向您展示如何使用它和范围和多量程类型如何帮助我们。
对于我们的示例,让我们假设您想要跟踪的日子和时间霍斯穿着他的克利夫兰布朗帽vs——他象帽(实际,对吧?)。

使用经典的SQL与范围
这是你如何将经典这样做:
|
1
2
3
4
5
6
7
8
9
10
11
|
创建
表
matts_hats_1
(
id
串行
主
关键
,
matts_hat
varchar
(
One hundred.
)
,
start_ts
时间戳
,
end_ts
时间戳
)
;
插入
成
matts_hats_1
(
matts_hat
,
start_ts
,
end_ts
)
值
(
棕色帽子的
,
“2021-10-01 6”
,
“2021-10-01 10点”
)
;
插入
成
matts_hats_1
(
matts_hat
,
start_ts
,
end_ts
)
值
(
“大象的帽子”
,
“2021-10-01 10点”
,
“2021-10-01 12:00”
)
;
插入
成
matts_hats_1
(
matts_hat
,
start_ts
,
end_ts
)
值
(
棕色帽子的
,
“2021-10-01”夏令时间
,
“2021-10-01 20:00”
)
;
插入
成
matts_hats_1
(
matts_hat
,
start_ts
,
end_ts
)
值
(
“大象的帽子”
,
“2021-10-01 22:00”
,
“2021-10-01点”
)
;
|
您可以插入这帽子我戴着当我启动和停止戴那顶帽子。看看帽子我戴在任何时候,我会使用:
|
1
2
3
4
|
yonk
=
#选择id, matts_hat从matts_hats_1 start_ts < = 2021-10-01 35::时间戳和end_ts > = 2021-10-01 35::时间戳;
id
|
matts_hat
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
1
|
布朗
帽子
|
看看帽子我戴着从早上7点到11点,我需要做一些调整。首先,我可能7点之前开始戴这顶帽子,可能11点后戴着帽子。为了找到这些,我需要看看开始时间与结束时间在早上7点和7点之前start_times在11点之前结束时间在11点之后。像这样:
|
1
2
3
4
5
6
|
yonk
=
#选择id, matts_hat从matts_hats_1 (start_ts < = 2021-10-01 07:00的:时间戳和end_ts > = 2021-10-01 07:00的::时间戳)或(start_ts < = 2021-10-01 11点::时间戳和end_ts > = 2021-10-01 11点::时间戳);
id
|
matts_hat
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
1
|
布朗
帽子
2
|
大象
帽子
(
2
行
)
|
这种方法的问题是,它很快就相当复杂,它否定适当的索引。认为我们试着添加索引:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
yonk
=
#上创建索引matts_hats_1_idx matts_hats_1 (start_ts end_ts);
创建
指数
yonk
=
#解释选择id, matts_hat从matts_hats_1 (start_ts < = 2021-10-01 07:00的:时间戳和end_ts > = 2021-10-01 07:00的::时间戳)或(start_ts < = 2021-10-01 11点::时间戳和end_ts > = 2021-10-01 11点::时间戳);
查询
计划
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
Seq
扫描
在
matts_hats_1
(
成本
=
0.00,1.08
行
=
1
宽度
=
222年
)
过滤器
:
(
(
(
start_ts
< =
“2021-10-01 07:00:00”
::
时间戳
没有
时间
区
)
和
(
end_ts
> =
“2021-10-01 07:00:00”
::
时间戳
没有
时间
区
)
)
或
(
(
start_ts
< =
“2021-10-01 11:00:00
::
时间戳
没有
时间
区
)
一个
D
(
end_ts
> =
“2021-10-01 11:00:00
::
时间戳
没有
时间
区
)
)
)
(
2
行
)
|
介绍在PostgreSQL范围
这就是“范围”数据类型。让我们看看这个数据和查询使用范围。
|
1
2
3
4
5
6
7
8
9
10
|
创建
表
matts_hats_2
(
id
串行
主
关键
,
matts_hat
varchar
(
One hundred.
)
,
hat_ts
tsrange
)
;
插入
成
matts_hats_2
(
matts_hat
,
hat_ts
)
值
(
棕色帽子的
,
“(2021-10-01 6,2021-10-01十点)”
)
;
插入
成
matts_hats_2
(
matts_hat
,
hat_ts
)
值
(
“大象的帽子”
,
“[2021-10-01十点,2021-10-01 12:00)”
)
;
插入
成
matts_hats_2
(
matts_hat
,
hat_ts
)
值
(
棕色帽子的
,
“(2021-10-01日14:00 2021-10-01 20:00)”
)
;
插入
成
matts_hats_2
(
matts_hat
,
hat_ts
)
值
(
“大象的帽子”
,
“[2021-10-01 22:00,2021-10-01 23:00)”
)
;
|
开箱即用的,您可以创建范围整数,数字、时间戳或日期,如果你需要其他数据(如一个浮点数)可以添加这些定制的(检查文档的更多信息)。你也可以把约束的范围,以防止数据重叠或执行一定的规则,但我不会盖在这个博客。
现在如果我们想找到帽子上面我穿着35点喜欢,我会发现有以下:
|
1
2
3
4
|
yonk
=
#选择id, matts_hat从matts_hats_2 hat_ts @ >“2021-10-01 35”::时间戳;
id
|
matts_hat
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
1
|
布朗
帽子
|
检查范围时注意不同的运营商?而不是“=“我使用“@ >”(控制操作符)。PostgreSQL有的运营商交互时使用范围。在这种情况下,@ >是检查左侧范围(hat_ts)包含价值2021-10-01 35。最常见的运营商,我使用这个博客:
| @ >、< @ | 看看一个元素或范围是或包含其他价值的一部分 |
| & & | 做范围的重叠 |
| + | 两个范围之间创建了一个联盟 |
| - - - - - - | 删除一个从另一个 |
还有其他的运营商,所以查看的文档在文档的完整列表。
现在把帽子我戴着早上7点到11点之间tsrange数据类型,我会发出以下命令:
|
1
2
3
4
5
|
yonk
=
#选择id, matts_hat从matts_hats_2 hat_ts & &(2021-10-01 7, 2021-10-01 11点)的;
id
|
matts_hat
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
1
|
布朗
帽子
2
|
大象
帽子
|
注意看起来干净了很多。在这种情况下,我们正在检查如果射程7 am-11与hat_ts字段。索引通过主旨也将使用范围的数据类型。
|
1
2
3
4
5
6
7
8
9
|
创建
指数
matts_hats_2_idx
在
matts_hats_2
使用
要点
(
hat_ts
)
;
yonk
=
#解释选择id, matts_hat从matts_hats_2 hat_ts & &”(“2021-10-01 7点”,“2021-10-01 11:00”)”;
查询
计划
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
位图
堆
扫描
在
matts_hats_2
(
成本
=
4.17,14.51
行
=
3
宽度
=
15
)
重新检查
气孔导度
:
(
hat_ts
& &
(“2021-10-01 07:00:00”、“2021-10-01 11:00:00”)”
::
tsrange
)
- >
位图
指数
扫描
在
matts_hats_2_idx
(
成本
=
0.00,4.17
行
=
3
宽度
=
0
)
指数
气孔导度
:
(
hat_ts
& &
(“2021-10-01 07:00:00”、“2021-10-01 11:00:00”)”
::
tsrange
)
|
我可以修改范围,添加或删除时间从什么已经存储。让我们继续和删除30分钟从我戴帽子的时间。
|
1
2
3
4
5
6
7
8
|
yonk
=
#更新matts_hats_2组hat_ts = hat_ts -(2021-10-01日14:00 2021-10-01 14:30)的id = 3;
更新
1
yonk
=
# select *从matts_hats_2 id = 3;
id
|
matts_hat
|
hat_ts
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
3
|
布朗
帽子
|
(
“2021-10-01 14:30:00”
,
“2021-10-01 20:00:00”
]
(
1
行
)
|
这个方法工作只要你缩小或扩展范围。然而,删除或添加范围变得棘手的(至少在PostgreSQL 14)当消除一系列的中间或添加一个不连续的戴帽子的时间。
|
1
2
|
yonk
=
#更新matts_hats_2组hat_ts = hat_ts -(2021-10-01 15:00, 2021-10-01下午15:30)的id = 3;
错误
:
结果
的
范围
区别
将
不
是
连续的
|
介绍多量程在PostgreSQL 14
PostgreSQL 14之前,您需要添加新记录,便于有多个非相邻块。然而,在PG14可以选择使用“多范围”类型。让我们看看这是如何工作的:
|
1
2
3
4
5
6
7
8
9
|
创建
表
matts_hats_3
(
id
串行
主
关键
,
matts_hat
varchar
(
One hundred.
)
,
hat_date
日期
,
hat_ts
tsmultirange
)
;
插入
成
matts_hats_3
(
matts_hat
,
hat_date
,
hat_ts
)
值
(
棕色帽子的
,
“2021-10-01”
,
”{2021-10-01 6,2021-10-01十点,[2021-10-01日14:00 2021-10-01 20:00]}”
)
;
插入
成
matts_hats_3
(
matts_hat
,
hat_date
,
hat_ts
)
值
(
“大象的帽子”
,
“2021-10-01”
,
”{[2021-10-01十点,2021-10-01 12:00),(2021-10-01 22:00时,2021-10-01 23:00)}”
)
;
|
你可以看到我所有的时间巩固戴着每一顶帽子为每一个记录。我可以运行相同的查询用于范围例子相同的结果。然而,现在我可以添加或删除额外的不连续的范围到记录:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
yonk
=
# select *从matts_hats_3 id = 1;
id
|
matts_hat
|
hat_date
|
hat_ts
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
1
|
布朗
帽子
|
2021年
- - - - - -
10
- - - - - -
01
|
{
(
“2021-10-01 06:00:00”
,
“2021-10-01 10:00:00”
]
,
(
“2021-10-01 14:00:00”
,
“2021-10-01 20:00:00”
]
}
(
1
行
)
yonk
=
#更新matts_hats_3设置hat_ts = hat_ts -{(2021-10-01 15:00, 2021-10-01下午15:30)}’,id = 1;
更新
1
yonk
=
# select *从matts_hats_3 id = 1;
id
|
matts_hat
|
hat_date
|
hat_ts
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
1
|
布朗
帽子
|
2021年
- - - - - -
10
- - - - - -
01
|
{
(
“2021-10-01 06:00:00”
,
“2021-10-01 10:00:00”
]
,
(
“2021-10-01 14:00:00”
,
“2021-10-01 15:00:00”
)
,
(
“2021-10-01 15:30:00”
,
“2021-10-01 20:00:00”
]
}
(
1
行
)
4
|
移除一块时间的中间距离现在创建一个第三个范围。这个功能可以非常有效和强大的存储的方式,看到时候是否活跃。这也可以用于审计和确定哪些条件是活跃在一定时期内。
警告:仅仅因为你并不意味着你应该做些什么。我无法找到任何硬限制数量的不同的范围可以存储在一个单一的领域。事实上,我能够增加超过100 k不同范围为一个字段没有PostgreSQL抱怨。说,修改或使用的性能,许多不同的范围可能很限制;这是尤其是告诉当添加或分裂范围。
更多101年在PostgreSQL使用范围
您可能已经注意到的范围会被“[]”;这有一个特殊的意义在PostgreSQL。他们指定的范围应该包括低/上界值在评估数据。这是一个快速入门:
| 范围 | 描述 |
| ( | 独家低范围值,觉得这像一个>(不包括指定的低价值) |
| ) | 独家上范围值,把它像一个<(不包括指定的上部值) |
| ( | 包容的范围价值低,觉得这像一个> =(包括指定的低价值) |
| ] | 包容性上范围值,把它像一个< =(包括指定的上部值) |
| {} | 这些都是预留给多量程数据类型 |
你可以想象如果你数据加载到一个测试表:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.
21
|
创建
表
test_range
(
int_range
int4range
,
int_mrange
int4multirange
,
ts_range
tsrange
,
ts_mrange
tsmultirange
,
my_desc
varchar
(
One hundred.
)
)
;
插入
成
test_range
值
(
“[1,10]”
,
{[1,4]、[6 10]}”
,
“(2021-10-01 10:30,2021-10-01 22:30)”
,
”{[2021-10-01 10:30,2021-10-01 12:30],[2021-10-01下午,2021-10-01 22:30]}”
,
“包容性上/包容下”
)
;
插入
成
test_range
值
(
“(1,10]”
,
{(1、4](6、10]}’
,
”(2021-10-01 10:30,2021-10-01 22:30]“
,
{(2021-10-01 10:30,2021-10-01 12:30)(2021-10-01下午,2021-10-01 22:30]}’
,
“包容性上/独家下”
)
;
插入
成
test_range
值
(
“(1)10)”
,
{(1、4)(10)}”
,
“(2021-10-01 10:30,2021-10-01 22:30)”
,
{(2021-10-01 10:30,2021-10-01 12:30)(2021-10-01下午,2021-10-01 22:30)}”
,
“独家上/独家下”
)
;
插入
成
test_range
值
(
“[1,10)”
,
{(1、4)[6、10)}’
,
“[2021-10-01 10:30,2021-10-01 22:30)”
,
{[2021-10-01 10:30,2021-10-01 12:30),[2021-10-01下午,2021-10-01 22:30)}
,
“独家上/包容下”
)
;
yonk
=
#从test_range select *;
int_range
|
int_mrange
|
ts_range
|
ts_mrange
|
my_desc
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
(
1
,
11
)
|
{
(
1
,
5
)
,
(
6
,
11
)
}
|
(
“2021-10-01 10:30:00”
,
“2021-10-01 22:30:00”
]
|
{
(
“2021-10-01 10:30:00”
,
“2021-10-01 12:30:00”
]
,
(
“2021-10-01 16:30:00”
,
“2021-10-01 22:30:00”
]
}
|
包容
上
/
包容
较低的
(
2
,
11
)
|
{
(
2
,
5
)
,
(
7
,
11
)
}
|
(
“2021-10-01 10:30:00”
,
“2021-10-01 22:30:00”
]
|
{
(
“2021-10-01 10:30:00”
,
“2021-10-01 12:30:00”
]
,
(
“2021-10-01 16:30:00”
,
“2021-10-01 22:30:00”
]
}
|
包容
上
/
独家
较低的
(
2
,
10
)
|
{
(
2
,
4
)
,
(
7
,
10
)
}
|
(
“2021-10-01 10:30:00”
,
“2021-10-01 22:30:00”
)
|
{
(
“2021-10-01 10:30:00”
,
“2021-10-01 12:30:00”
)
,
(
“2021-10-01 16:30:00”
,
“2021-10-01 22:30:00”
)
}
|
独家
上
/
独家
较低的
(
1
,
10
)
|
{
(
1
,
4
)
,
(
6
,
10
)
}
|
(
“2021-10-01 10:30:00”
,
“2021-10-01 22:30:00”
)
|
{
(
“2021-10-01 10:30:00”
,
“2021-10-01 12:30:00”
)
,
(
“2021-10-01 16:30:00”
,
“2021-10-01 22:30:00”
)
}
|
独家
上
/
包容
较低的
(
4
行
)
|
最终的想法
数据类型范围已经是一个独特而强大的特性来存储多个不连续的范围。之外,开发者将有另一个工具的工具箱得到更多PostgreSQL。
随着越来越多的公司看从Oracle迁移或实施的新数据库与应用程序,PostgreSQL通常是最好的选择对于那些想要在开放源代码数据库上运行。
读我们的新白皮书:
为什么客户选择为PostgreSQL Pe雷竞技下载官网rcona吗




