这篇文章最初发表于2019年并于2023年被更新。
我在雷竞技下载官网Percona圣保罗大学PostgreSQL的新特性,允许部署简单的碎片。我试着总结这篇文章的主要观点,以及提供一个介绍性的概述分片本身。请注意我没有包含任何第三方扩展提供PostgreSQL分片在我下面的讨论。
PostgreSQL分区
简而言之,直到不久之前,没有一个专门的,本机功能PostgreSQL的表分区。不是阻止人们这样做无论如何:PostgreSQL社区很有创造力。有一个PostgreSQL表继承特性,允许创建子表具有相同结构作为一个父表。,结合就业每个子表的适当的约束和正确的触发在父表中,提供了实用的“表分区”PostgreSQL多年(现在仍然)工作。这里有一个例子:
用表继承
|
1
2
3
4
5
6
|
创建
表
温度
(
id
BIGSERIAL
主
关键
不
零
,
city_id
INT
不
零
,
时间戳
时间戳
不
零
,
临时
小数
(
5
,
2
)
不
零
)
;
|
图1 a。主要(或父母)表
|
1
2
3
|
创建
表
temperature_201901
(
检查
(
时间戳
> =
日期
“2019-01-01”
和
时间戳
< =
日期
“2019-01-31”
)
)
继承了
(
温度
)
;
创建
表
temperature_201902
(
检查
(
时间戳
> =
日期
“2019-02-01”
和
时间戳
< =
日期
“2019-02-28”
)
)
继承了
(
温度
)
;
创建
表
temperature_201903
(
检查
(
时间戳
> =
日期
“2019-03-01”
和
时间戳
< =
日期
“2019-03-31”
)
)
继承了
(
温度
)
;
|
图1 b。子表继承父表的结构和有限的约束
|
1
2
3
4
5
6
7
8
9
10
11
12
|
创建
或
取代
函数
temperature_insert_trigger ()
返回
触发
作为
$ $
开始
如果
(
新。时间戳
>=
日期
“2019-01-01”
和
新。时间戳
<=
日期
“2019-01-31”
)
然后
插入
成
temperature_201901
值
(新. *);
ELSIF
(
新。时间戳
>=
日期
“2019-02-01”
和
新。时间戳
<=
日期
“2019-02-28”
)
然后
插入
成
temperature_201902
值
(新. *);
ELSIF
(
新。时间戳
>=
日期
“2019-03-01”
和
新。时间戳
<=
日期
“2019-03-31”
)
然后
插入
成
temperature_201903
值
(新. *);
其他的
提高异常
“日期范围的!”;
如果;
返回
零;
结束;
$ $
语言
plpgsql;
|
图1 c。控制函数的子表应该添加一个新条目根据时间戳字段
|
1
2
3
|
创建
触发
insert_temperature_trigger
之前
插入
在
温度
为
每一个
行
执行
过程
temperature_insert_trigger
(
)
;
|
图1 d。触发器被添加到父表调用上面的函数在执行插入。
这样的实现最大的缺点是所需的手动工作来维持这样一个环境中(尽管一定程度的自动化可以通过使用第三方扩展等pg_partman)和缺乏优化/支持“分布式”查询。PostgreSQL优化器不够先进的分区有很好的理解,虽然有解决方法可以使用,如使用约束排斥。
声明式分区
大约1.5年前,PostgreSQL 10发布了许多新特性,包括原生支持表分区通过新的声明性分区功能。这是如何分区温度相同表使用这种新方法:
|
1
2
3
4
5
6
|
创建
表
温度
(
id
BIGSERIAL
不
零
,
city_id
INT
不
零
,
时间戳
时间戳
不
零
,
临时
小数
(
5
,
2
)
不
零
)
分区
通过
范围
(
时间戳
)
;
|
图2 a。主分区表的表结构
|
1
2
3
|
创建
表
temperature_201901
分区
的
温度
为
值
从
(
“2019-01-01”
)
来
(
“2019-02-01”
)
;
创建
表
temperature_201902
分区
的
温度
为
值
从
(
“2019-02-01”
)
来
(
“2019-03-01”
)
;
创建
表
temperature_201903
分区
的
温度
为
值
从
(
“2019-03-01”
)
来
(
“2019-04-01”
)
;
|
图2 b。表定义为分区的主要表;与声明性分区,不需要触发了。
它仍然错过了更大的优化和灵活性需要考虑一个完整的分区方案。它是不可能的,例如,执行更新,会导致一行从一个分区转移到另一个,但已经奠定了基础。快进一年,PostgreSQL 11建立在此之上,提供额外的功能,如:
- 定义一个默认的分区的可能性,任何条目不符合相应的分区将被添加到。
- 有索引添加到主要表“复制”到底层的分区,以改善声明性分区的可用性。
- 支持外键
这些只是几个特性,导致一个更成熟的分区方案。
PostgreSQL分片
现在,你可能会质疑我的前提和合理分区分片,至少不是和你会想到这篇文章上下文。事实上,PostgreSQL之上实现分片分区,允许任何分区的分区表由一个远程服务器。这是在PostgreSQL的外交的基础数据包装器(给水)的支持,这一直是一个核心的PostgreSQL的一部分很长一段时间。在技术上可以实现,我们不能让分片实际地使用它使用表继承+触发器的方法。声明式分区允许更好的集成这些作品进行分片,分区表由远程服务器——在PostgreSQL的现实。
|
1
2
3
4
5
6
|
创建
表
temperature_201904
(
id
BIGSERIAL
不
零
,
city_id
INT
不
零
,
时间戳
时间戳
不
零
,
临时
小数
(
5
,
2
)
不
零
)
;
|
图3一。在远程服务器上,我们创建一个“分区”——一个简单的表。
|
1
2
3
4
5
6
7
|
创建
扩展
postgres_fdw
;
格兰特
使用
在
外国
数据
包装器
postgres_fdw
来
app_user
;
创建
服务器
shard02
外国
数据
包装器
postgres_fdw
选项
(
dbname
“postgres”
,
主机
“shard02”
,
港口
“5432”
)
;
创建
用户
映射
为
app_user
服务器
shard02
选项
(
用户
“fdw_user”
,
密码
“秘密”
)
;
|
图3 b。在本地服务器上,预备步骤涉及加载postgres_fdw扩展,扩展我们的本地应用程序允许用户使用,创建一个条目来访问远程服务器,并最终映射,用户与用户在远程服务器(fdw_user),本地访问表我们将使用作为远程分区。
|
1
2
3
|
创建
外国
表
temperature_201904
分区
的
温度
为
值
从
(
“2019-04-01”
)
来
(
“2019-05-01”
)
服务器
remoteserver01
;
|
图3 c。现在简单的创建一个适当的分区的主要表在当地服务器将与表相同名称的远程服务器。
你可以阅读更多关于postgres_fdw外国数据包装在PostgreSQL和仔细看看postgres_fdw。
当对表进行分区的意义吗?
有几个主要原因分区表:
- 当一个表增长如此之大,搜索的帮助下变得不切实际甚至索引(这总是会变得太大)。
- 当数据管理的目标数据通常是最近添加和/或旧数据不断清除/存档,甚至没有被搜查了(至少不是经常)。
- 如果你是来自不同数据源的数据加载和维护数据仓库的报告和分析。
- 便宜存档或清除大量的数据,避免独家锁定整个表。
我们应该采取分片?
这里有几个经典案例:
- 规模(水平),即使在分区表时,太大或太复杂的数据量是由单个服务器处理。
- 用例的大表中的数据可以分为两个或两个以上的部分,大部分的搜索模式中受益。这样的一个场景的一个常见的例子是一个公司的客户是均匀地分布在美国和其搜索目标表包含客户的邮政编码。碎片可以被用于主机条目的客户位于东海岸和西海岸的客户。
- 切分也可以用来减少查询的复杂性将大表分成更小的、更容易管理的部分。这可能导致更快的查询响应时间和改善最终用户的性能。
- 在某些情况下,分片可以用来解决监管或合规需求通过物理分离数据有不同程度的敏感性或访问需求。这可以帮助组织满足他们的法律义务,并确保适当的数据存储和访问。
注意,这决不是一个广泛的列表。
我们应该如何切分数据?
用分片(在这种情况下)被“分布式”分区,一个成功的本质(性能)分片环境在于选择正确的切分的关键——“没错,”我的意思是,能使您的数据在多个碎片的方式将有利于你的查询。在上面的示例中,使用客户邮编碎片键是有道理的,如果应用程序经常会发出查询,将达到一个碎片(东)或其他(西)。然而,如果大多数查询过滤,说,出生日期,然后所有查询需要运行在所有碎片恢复完整的结果集。这很容易适得其反与切分方法,对性能没有选择正确的切分键或只是通过这样一个异构负载,没有碎片关键能够满足它。
只意义切分如果查询涉及到目标表的性质(s)是分布式处理将成为常态,构成一个优势远远大于任何依赖的查询开销由少数连接涉及多个碎片。由于分片的分布式特性,这样的查询一定会执行相比,更糟糕的是,如果让他们都驻留在相同的服务器上。
在我们的博客上了解更多关于分片键,选择一个好的分片键MongoDB (MySQL)。
为什么不简单地依赖于复制或集群?
切分应该考虑当你不能有效地分解一个大表通过数据标准化或使用另一种方法。保持它在单一服务器过于苛刻。表分区,分区分布在不同的服务器负载分散到许多服务器。它不需要一个分区/碎片;通常,一个碎片将主办一个分区的数量。
注意分片有别于传统的“分享”数据库复制和集群环境:你可以使用,例如,一个专门的PostgreSQL服务器主机单个分区从一个表。然而,这些数据缩放技术很可能相互补充:PostgreSQL数据库可能举办一个碎片与大桌子的一部分以及复制小表,通常用于一些咨询(只读),如价格单,通过逻辑复制。
实现PostgreSQL分片的最佳实践是什么?
在PostgreSQL中实现分片可以是一个复杂的过程,但一些最佳实践可以帮助确保项目的成功。这里有一些重要的注意事项和实践:
- 评估需要分片:在实现分片PostgreSQL,评估是否有必要为您的应用程序。分片可以帮助提高性能和可伸缩性,但是它还增加了数据库架构的复杂性。考虑您的应用程序的工作负载和增长预测,以确定切分是必要的。
- 选择一个分片策略:有几个分片策略可供选择,包括水平、垂直和功能切分。每个策略都有自己的优点和缺点,所以选择一个最适合您的应用程序的需求。考虑数据分布等因素,选择分片时查询模式和硬件需求的策略。
- 数据迁移计划:迁移数据分片数据库可以是一个复杂和耗时的过程,所以制定计划迁移数据,包括测试和验证,以确保数据的完整性。考虑使用工具,如pg_dump和pg_restore简化迁移过程。
- 备份和恢复策略:分片可以添加备份和恢复过程的复杂性,所以重要的是要提前计划,这些过程。考虑使用备份工具支持数据库分片。开发一个恢复计划以确保数据可以在发生灾难中恢复过来。
- 测试彻底:部署数据库分片投入生产之前,必须彻底地测试它。测试的分片策略,应用程序架构,和灾难恢复过程,如上所述。
- raybet雷竞技竞猜在线官网监控和优化性能:分片可以帮助提高性能,但它也引入了新的性能的挑战。raybet雷竞技竞猜在线官网定期监控数据库性能和优化您的数据库。考虑使用工具,如pg_stat_statements pgAdmin来帮助识别和优化您的数据库性能问题。
优化你的PostgreSQL数据库通过实现分片与性能和可伸缩性raybet52 。
PostgreSQL的分片与MongoDB分片如何?
MongoDB®直通解决管理的问题大集合分片:没有本地分区MongoDB的集合的概念。事实上,整个MongoDB扩展策略是基于分片的,这需要一个中心位置的数据库架构。因此,MongoDB分片过程已经变得尽可能透明的应用程序:所有DBA定义碎片的关键。
而不是连接到数据库服务器的引用,这个应用程序将连接到一个辅助路由器服务器命名蒙戈,这将处理查询和请求必要的信息以各自的碎片。它知道它碎片包含什么,因为他们保持元数据的一个副本地图的数据块碎片,它们得到的配置服务器,另一个重要的、独立的组件的MongoDB集群分片。在一起,他们也扮演了一定的角色保持良好的数据分布的碎片,积极分裂和迁移服务器之间的数据块。
在PostgreSQL,应用程序将连接和查询主数据库服务器。没有一个中间路由器之类的蒙戈,但PostgreSQL的查询计划将处理查询和创建一个执行计划。当数据请求从一个分区表被发现在一个远程服务器上,PostgreSQL将请求数据,如下解释输出所示:
|
1
2
3
4
5
6
7
|
…
远程
SQL
:
更新
公共
.emp
集
萨尔
=
美元
2
在哪里
ctid
=
美元
1
- >
嵌套的
循环
(
成本
=
100.00,300.71
行
=
669年
宽度
=
118年
)
输出
:
电磁脉冲
.empno
,
电磁脉冲
.ename
,
电磁脉冲
.job
,
电磁脉冲
.mgr
,
电磁脉冲
.hiredate
,
(
电磁脉冲
.sal
*
“1.1”
::
双
精度
)
,
电磁脉冲
.comm
,
电磁脉冲
.deptno
,
电磁脉冲
.ctid
,
salgrade
.ctid
加入
过滤器
:
(
(
电磁脉冲
.sal
>
(
salgrade
.losal
)
::
双
精度
)
和
(
电磁脉冲
.sal
<
(
salgrade
.hisal
)
::
双
精度
)
)
- >
外国
扫描
在
公共
.emp
(
成本
=
100.00,128.06
行
=
602年
宽度
=
112年
)
输出
:
电磁脉冲
.empno
,
电磁脉冲
.ename
,
电磁脉冲
.job
,
电磁脉冲
.mgr
,
电磁脉冲
.hiredate
,
电磁脉冲
.sal
,
电磁脉冲
.comm
,
电磁脉冲
.deptno
,
电磁脉冲
.ctid
…
|
图4:摘录的解释计划涉及到处理一个查询在一个远程服务器。
注意在上面的提到“远程SQL查询。“许多优化了远程查询的执行在PostgreSQL 10和11,这导致了成熟和提高切分的解决方案。其中之一是支持分组和聚合操作在远程服务器上执行(“压低”),而不是在本地恢复所有行和处理它们。
失踪在PostgreSQL的实现是什么?
然而,还是改进的余地。关于远程执行,来自社区的报告表明不是所有的查询都应该执行。例如,在某些情况下,PostgreSQL规划师不是执行一个完整的下推,导致碎片转移比需要更多的数据。的查询的并行调度联系多个碎片还没有实现:现在,执行顺序发生,一次一个碎片,这需要更长的时间才能完成。时维护分区、分片环境,改变分区的结构仍然是复杂和不切实际的。例如,当你添加一个新的分区,分区表指定默认的分区,您可能需要分离的默认分区前如果它包含行现在将适合在新分区,手动将这些新的分区,最后,系统默认的分区在的地方。
但这都是成熟技术的一部分。我们期待PostgreSQL 12和分区和分片方面将会带来什么。
优化和规模与Percona Postgres环境雷竞技下载官网
如果你感兴趣实现PostgreSQL分片或正在寻找一个更完整的分区方案,Percona可以提供帮助。雷竞技下载官网
雷竞技下载官网Percona提供各种服务和支持选项来帮助你优化和规模raybet52 数据库环境。从咨询,管理服务,和支持,P雷竞技下载官网ercona资源和专长,帮助你充分利用你的PostgreSQL部署。lol赔率雷电竞 或请求一个演示要学习更多的知识。
雷竞技下载官网Percona分布PostgreSQL提供最好的和最关键的企业组件从开源社区在一个分布,设计和测试一起工作。
- - - - - -
基于照片的图像莱昂纳多Quatrocchi从Pexels







写的非常有趣,谢谢你!但是,你写的:
“这只意义切分如果查询涉及到目标表的性质(s)是分布式处理将规范[…]由于分片等查询的分布式特性必然会执行相比,更糟糕的是,如果让他们都驻留在同一台服务器上。”
尽管我完全明白你的意思,我想知道为什么它不应该有利于减少数据在每一个碎片。所以即使查询点击每一个碎片,每个碎片都有工作通过更少的数据(10碎片只有十分之一)。当然是有益的,但它要求并行查询发送到所有碎片,没有实现在PostgreSQL的最后你写你的文章,但我认为它将在不久的将来,已经是早期以来mongoDB。
你知道扩展Citus吗?https://www.citusdata.com/
感谢信息。非常有用。
很有趣。我希望未来的分片将允许更多的动态作业。在SaaS空间,监管的承诺要求大多数PII服务过程或其他客户数据从他们的系统完全删除这些数据及时,我看不到这个业务需要被解决在当今市场上。
考虑一个多租户SaaS解决方案,您可以包括
tenant_id在每个表列。我们应该能够为数据库存储设置“违约”,允许创建一个新的分区的在一个新的远程文件来存储这些数据。同样,客户应该终止关系,它应该是一个简单的远程文件…但我们仍然相当远,它的样子。