v11文档
PostgreSQL支持三种分表方式:范围分区(RANGE)、列表分区(LIST)和哈希分区(HASH)。

  1. 范围分区(RANGE):按照某列(或某几列)的值划分成互不重叠的区间,如按时间按月划分订单表。
  2. 列表分区(LIST):按照枚举出的值进行分区,例如按国家划分客户表。
  3. 哈希分区(HASH):根据某列(或某几列)的哈希值对模取余,余数相同的划分到同一分区,如按产品编号哈希分区的产品表。

PostgreSQL 10.x版本之前,分表需要使用继承和触发器来实现,但从PostgreSQL 10.x版本开始,引入了声明式的分表方式,更加简化操作。

版本特性:

先根据省份代码列表分区,然后根据时间按月范围分区

DO $$
DECLARE
    province_codes VARCHAR[] := ARRAY[
        '110000', '120000', '130000', '140000', '150000', '210000', '220000', '230000',
        '310000', '320000', '330000', '340000', '350000', '360000', '370000', '410000',
        '420000', '430000', '440000', '450000', '460000', '500000', '510000', '520000',
        '530000', '540000', '610000', '620000', '630000', '640000', '650000', '710000',
        '810000', '820000'
    ];
    province_code CHAR(6);
    sql_query TEXT;
BEGIN
    -- 1. 创建主分区表 fire_points_partitioned
    CREATE TABLE IF NOT EXISTS fire_points_partitioned (
        id SERIAL,
        fire_time TIMESTAMP,
        province_code CHAR(6),
        city_code CHAR(6),
        county_code CHAR(6),
        town_code VARCHAR(50),
        latitude NUMERIC(8, 6),
        longitude NUMERIC(9, 6),
        shape GEOMETRY
    ) PARTITION BY LIST (province_code);
 
    -- 2. 根据省份代码列表创建对应的分区表
    FOREACH province_code IN ARRAY province_codes
    LOOP
        -- 3. 创建省份分区表
        sql_query := format(
            'CREATE TABLE IF NOT EXISTS fire_points_partitioned_%s PARTITION OF fire_points_partitioned FOR VALUES IN (%L)',
            province_code, province_code
        );
        EXECUTE sql_query;
    END LOOP;
     
    -- 4. 添加索引
    EXECUTE 'CREATE INDEX IF NOT EXISTS idx_fire_points_partitioned_province_code ON fire_points_partitioned (province_code)';
    EXECUTE 'CREATE INDEX IF NOT EXISTS idx_fire_points_partitioned_fire_time ON fire_points_partitioned (fire_time)';
     
END;
$$;

这样,fire_points_partitioned表将根据省份代码进行列表分区,并在province_code和fire_time字段上添加索引。