postgresql 将每个服务器的长范围作为数据库分片的主键有什么缺点?

k97glaaz  于 2023-02-12  发布在  PostgreSQL
关注(0)|答案(2)|浏览(187)

我正在设计一个分片数据库。很多时候我们使用两列,第一列用于逻辑分片,第二列用于唯一标识分片中的一行。相反,我计划只使用长数据类型的1列作为主键。为了在服务器上使用唯一的键,我计划使用bigserial,它将生成不重叠的范围。
| 伺服器|PK开始于|主键结束于|
| - ------|- ------|- ------|
| 1个|1个|九九十九万九千九百九十九九十九|
| 第二章|一千万|一万九千九十九万九千九百九十九|
| 三个|两千万|二万九千九十九万九千九百九十九|
| 四个|三千亿|三万九千九十九万九千九百九十九|
| 五个|四千万|四万九千九十九万九千九百九十九|
等等。
以后我应该可以
1.将大型服务器拆分为两个或多个小型服务器
1.将两个或多个小型服务器连接到一个大型服务器
1.将一些行从服务器A移动到服务器B,以更好地利用资源。
我也将有一个查找表,其中将包含范围和目标服务器的信息。

    • 我想了解此方法的缺点。**
jtoj6r0c

jtoj6r0c1#

我建议您在服务器1上创建主键列,如下所示:

CREATE TABLE ... (
   id bigint GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1000),
   ...
);

在第二台服务器上使用START WITH 2,依此类推。
添加一个新的分片很简单,只需要使用一个新的起始值。拆分或合并分片是微不足道的(就主键而言......),因为新值永远不会与旧值冲突,并且每个分片生成不同的值。

ajsxfq5m

ajsxfq5m2#

两种最常见的分片密钥类型基本上是:

  • 基于确定性表达式,如@LaurenzAlbe的答案中建议的基于模的方法。
  • 基于查找表,就像你在文章中描述的方法。

后一种类型的缺点是,你的应用必须频繁地检查查找表(甚至可能在每次查询时),因为范围可能会改变。存储在查找表中的范围可能是一个好东西,放在缓存中,以避免频繁的SQL查询。然后在你改变它们时替换缓存的范围。我认为这不会经常发生。有了缓存,这是一个相当温和的缺点。
我曾在这样一个系统中工作过,我们为每个客户分配了一个模式,分布在8个碎片上。在每个会话开始时,应用程序都会查询查找表,以找出相应客户的数据存储在哪个碎片上。大约一年一次,我们会将一些客户模式移动到新的碎片上。因为它们自然会增长。这包括更新查找表。这是一个不错的解决方案。
我建议您最终在每个服务器上使用多个不连续的范围,因为存在数据或流量的热点,如果您希望移动最少的数据量,则拆分范围是有意义的。
| 伺服器|PK开始于|主键结束于|
| - ------|- ------|- ------|
| 1个|1个|九九十九万九千九百九十九九十九|
| 第二章|一千万|一万九千九十九万九千九百九十九|
| 三个|两千万|二万九千九十九万九千九百九十九|
| 四个|三千亿|三千二百九十九万九千九九万九千九百九十九|
| 三个|三千三百万|二万九千九十九万九千九百九十九|
| 五个|四千万|四万九千九十九万九千九百九十九|
如果您希望不时地移动数据子集,则这可能是比基于表达式的分片类型更好的设计。如果您使用表达式,并且需要在分片之间移动数据,则必须创建更复杂的表达式,或者重新平衡大量数据。

相关问题