数据分区是一种将大型数据集划分为更小、更易于管理的部分的技术,这些部分称为分区。这些分区通常分布在多个数据库表中,包含自己的数据子集,并且可以重叠或不重叠。每个分区都可以被视为一个单独的数据库,但它们仍然是同一个逻辑数据库的一部分。
数据库分区的目的是提高数据库的性能、可扩展性和可用性。通过将数据划分为更小的部分,管理和处理大量数据变得更加简单。
让我们首先概述一下数据分区为何重要、它是如何工作的以及它的类型。
您可能需要出于多种原因对数据库进行分区,包括以下原因
提高性能:对数据库进行分区可以显著提高查询和事务的性能。通过将大型数据库划分为更小的分区,我们可以减少需要处理的数据量,并通过减少对 CPU 和 I/O 等共享资源的争用来提高查询速度。
可用性:虽然可用性不是分区的“副产品”,但通过将数据划分为多个更小的分区,我们可以创建数据的冗余副本(副本),并将这些分区分布在多个系统中。这有助于确保即使一个分区或服务器出现故障,数据仍然可用。尽管如此,可用性可以被视为数据分区的一个目标,而不是结果。
可扩展性:对数据库进行分区可以更容易地随着数据大小和复杂性的增加而扩展数据库。通过将数据划分为更小的分区,我们可以添加更多服务器或存储设备来处理增加的工作负载。
可管理性:对数据库进行分区可以使其更易于管理。通过将数据划分为更小的分区,我们可以简化备份、维护和其他管理任务。
数据库分区有多种方法,包括水平分区、垂直分区和混合分区。水平分区涉及到根据行划分数据,而垂直分区涉及到根据列划分数据。
混合分区是水平分区和垂直分区的组合。
数据库分区可以在数据库架构的各个级别实现,包括应用程序级别和数据库级别。使用的具体分区方法取决于应用程序的需求和所存储数据的特征。
在分布式数据库中,分区用于拆分存储的数据,并将整个数据库中的一小部分分配给集群的节点。每个节点只存储数据集的一部分。
在大多数分布式数据库中,“分区”和“分片”这两个术语可以互换使用。对数据进行分片并将其分布在多个系统中,使数据库可以使用比单台计算机更多的资源来存储和处理数据集。
在这些系统中,分区也与复制一起使用。这意味着一个分区被分配给分布式系统的多个节点。这可以提高数据的可用性。如果其中一个节点出现故障,仍然可以从另一个系统访问数据。
例如,您可以在具有四个节点(A、B、C 和 D)的集群中使用水平范围分区对客户数据进行分区。客户 ID 介于 0 到 1,000 之间的客户存储在系统 A 上。此外,该分区还在系统 B 中复制。客户 ID 从 1,001 到 2,000 的客户数据存储在系统 C 上,并且相同的分区也复制到系统 D 中。
如果必须访问 ID 为 50 的客户,则必须联系系统 A 或 B 以从正确的分区加载数据。如果其中一个系统不可用(例如,由于崩溃),您仍然可以从剩余的系统访问数据,因为即使某些系统无法运行,它仍然可用。
在 Timescale 中,我们同时使用空间和时间分区来改进数据分布。
通过使用水平分区,表的完整行被分配给分区。因此,每个分区包含相同的属性,但元组(在关系数据库中,如 PostgreSQL 和 Timescale,一个元组就是一条记录,即一行)比整个数据集少。通常,这种类型的分区是不重叠的。这意味着一个元组只属于一个分区。
您可以使用多种策略(如上面讨论的列表、范围或哈希分区)执行分配。
例如,当使用水平分区来使用范围分区对客户数据进行分区时,分区 A 包含客户 ID 为 0-1,000 的客户的元组,而分区 B 包含客户 ID 为 1,001-2,000 的客户的元组。
在列表分区中,数据根据表中特定列的预定义值列表划分为分区。每个分区包含与列表中的特定值匹配的行。例如,客户表可能会根据他们所在的州进行分区,每个分区包含特定州的客户的行。
在范围分区中,数据根据表中特定列的值范围划分为分区。每个分区包含落入特定值范围内的行。例如,销售交易表可能会根据交易日期进行分区,每个分区包含特定日期范围内的行。
在哈希分区中,数据根据应用于表中特定列的哈希函数划分为分区。哈希函数生成一个值,该值用于将每一行分配给特定的分区。当没有明显的范围或列表可供分区时,哈希分区非常有用。
这是一种数据库分区技术,它结合了多种分区方法来创建更复杂的分区。在复合分区中,使用两种或多种分区方法对表进行分区。
例如,可以首先使用基于日期列的范围分区对表进行分区。然后,可以使用基于客户所在州的列表分区进一步划分每个分区。这将导致使用范围和列表分区的复合分区方案。
当单一的分区方法不足以创建均匀的数据分布时,复合分区非常有用。通过组合多种分区方法,复合分区可以提供更大的灵活性,并允许使用更复杂的分区方案。
但是,与更简单的分区方法相比,复合分区的实现和管理也可能更加复杂,并且可能需要更多资源。与任何分区方法一样,选择使用复合分区取决于数据库和应用程序的特定要求。
这种简单的数据库分区技术以轮询方式将数据均匀分布在一组分区中。在轮询分区中,每个新行或记录都以循环方式分配给下一个可用的分区。
例如,假设我们有三个分区,并希望使用轮询分区对销售交易表进行分区。第一行将被分配给第一个分区,第二行将被分配给第二个分区,第三行将被分配给第三个分区。然后,第四行将再次分配给第一个分区,依此类推。
当没有明确的键或属性用于分区,或者不需要更复杂的分区方案时,轮询分区非常有用。但是,轮询分区可能并非对所有应用程序都是最佳选择,因为它可能无法为查询处理提供最佳性能。这是因为所有分区都需要由大多数查询进行处理(即,无法确定哪些分区包含计算特定查询所需的数据,因为没有关于分区分配规则的明确数据)。
回到我们之前的例子,如果您进行范围分区并将客户 ID 为 0-1,000 的客户存储在分区 A 中,将客户 ID 为 1,001-2,000 的客户存储在分区 B 中,并查询数据库以查找客户 ID 为 50 的客户,您就知道只需要访问分区 A。这是一个精确的、确定的分区。
但是,如果您通过轮询分区分配客户并进行相同的查询,您将不知道该特定记录存储在哪个分区中。
总的来说,轮询分区是一种简单的数据库分区技术,在某些情况下可能很有用,但可能不是所有应用程序的最佳选择。
通过使用垂直分区,元组的属性被拆分并分配给不同的分区。每个分区包含相同数量的元组,但属性数量不同。
在大多数情况下,一个属性(通常是主键)是所有分区的一部分。此属性用于在读取元组时重建元组。属于每个分区的属性通常在创建分区时直接由其名称指定。
例如,客户实体包含以下属性:customer id
、firstname
、lastname
和 email
。属性 customer id
、firstname
、lastname
分配给分区一,属性 customer id
和 email
分配给分区二。读取元组时,使用 customer id
将分区 A 的属性与分区 B 的属性组合在一起。
您可以使用垂直分区将不同的属性分区存储在单独的存储卷上。这允许将访问频率较低的属性存储在速度较慢、成本效益更高的卷上,而将访问或修改频率较高的属性存储在速度更快、成本更高的卷上。另一种应用是为这些分区分配不同的权限,以限制对某些属性的访问。
混合分区结合了水平分区和垂直分区。因此,使用水平分区将元组分配给不同的分区,并使用垂直分区对元组的属性进行分区并分配给不同的分区。因此,每个分区包含的属性和元组都比整个数据集少。
即使这样的分区方案管理起来更加复杂,但它允许创建小的分区并对某些属性进行不同的处理(例如,将它们存储在不同的卷上;请参阅垂直分区)。
在使用客户和范围分区的示例中,客户元组根据客户 ID 分配给分区。然后,对元组的属性进行分区。因此,客户 ID 为 0-1,000 的客户的属性 customer id
、firstname
和 lastname
存储在分区 A 中,而客户 ID 为 0-1,000 的客户的属性 customer id
和 email
存储在分区 B 中。
既然您已经学习了数据分区的基础知识,请阅读更多关于 何时应该考虑使用 Postgres 分区。