PostgreSQL表分区
Eave
2025.11.13
PostgreSQL支持基本的表分区功能。分区的意思是把逻辑上的一个大表分割成物理上的几块。分区可以提供若干好处:
这种好处通常只有在表可能会变得非常大的情况下才有价值。到底多大的表会从分区中收益取决于具体的应用, 不过有个基本的拇指规则就是表的大小超过了数据库服务器的物理内存大小。
目前,PostgreSQL支持通过表继承进行分区。每个分区必须做为单独一个父表的子表进行创建。父表自身通常是空的,它的存在只是为了代表整个数据集。你在试图实现分区之前,应该先熟悉继承。
PostgreSQL可以实现下面形式的分区:
范围分区:表被一个或者多个关键字段分区成"范围",这些范围在不同的分区里没有重叠。比如,我们可以为特定的商业对象根据数据范围分区,或者根据标识符范围分区。
列表分区:表通过明确地列出每个分区里应该出现那些关键字值实现。
要设置一个分区的表,做下面的步骤:
创建"主表",所有分区都从它继承。
这个表中没有数据,不要在这个表上定义任何检查约束,除非你希望约束同样也适用于所有分区。同样,在其上定义任何索引或者唯一约束也没有意义。
创建几个"子表",每个都从主表上继承。通常,这些表不会增加任何字段。
我们将把子表称作分区,尽管它们就是普通的PostgreSQL表。
给分区表增加约束,定义每个分区允许的健值。
典型的例子是:
CHECK ( x = 1 )
CHECK ( county IN ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire' ))
CHECK ( outletID >= 100 AND outletID < 200 )
确保这些约束能够保证在不同的分区里不会有重叠的键值。一个常见的错误是设置下面这样的范围:
CHECK ( outletID BETWEEN 100 AND 200 )
CHECK ( outletID BETWEEN 200 AND 300 )
比如,假设我们为一个巨大的冰激凌公司构造数据库。该公司每天都测量最高温度,以及每个地区的冰激凌销售。概念上,我们需要一个这样的表:
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
);
然后我们为每个月创建一个分区
CREATE TABLE measurement_200602 (
CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' )
) INHERITS (measurement);