PostgreSQL 11 新特性解读:分区表支持创建主键、外键、索引

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB PostgreSQL 版,企业版 4核16GB
推荐场景:
HTAP混合负载
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: PostgreSQL 10 版本虽然支持创建范围分区表和列表分区表,但创建过程依然比较繁琐,需要手工定义子表索引、主键,详见 PostgreSQL10:重量级新特性-支持分区表,PostgreSQL 11 版本得到增强,在父表上创建索引、主键、外键后,子表上将自动创建,本文演示这三种场景。

PostgreSQL 10 版本虽然支持创建范围分区表和列表分区表,但创建过程依然比较繁琐,需要手工定义子表索引、主键,详见 PostgreSQL10:重量级新特性-支持分区表,PostgreSQL 11 版本得到增强,在父表上创建索引、主键、外键后,子表上将自动创建,本文演示这三种场景。

值得一提的是,11 版本之前 PostgreSQL 的分区表不支持全局主键,虽然可以在父表和子表上分别定义主键,但不支持全局主键,也就是说,父表和子表、子表和子表的主键数据可以重复。

手册上的 Release 说明

Support for PRIMARY KEY, FOREIGN KEY, indexes, and triggers on partitioned tables

本文以创建哈希分区表为例进行测试。

测试环境准备

创建分区表并插入测试数据,为后续测试做准备。

创建父表

CREATE TABLE userinfo (
 userid    int4,
 username  character varying(64),
 ctime   timestamp(6) without time zone
) PARTITION BY HASH(userid);

创建子表

CREATE TABLE userinfo_p0 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 0);
CREATE TABLE userinfo_p1 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 1);
CREATE TABLE userinfo_p2 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 2);
CREATE TABLE userinfo_p3 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 3);

插入数据

给分区表插入100万数据,如下:

INSERT INTO userinfo(userid,username,ctime) SELECT n, n || '_username',clock_timestamp() FROM generate_series(1,1000000) n;

测试一: 创建主键

在父表上创建主键,如下。

ALTER TABLE userinfo ADD PRIMARY KEY (userid);

在父表上查看,如下。

francs=> \d userinfo
                          Table "francs.userinfo"
  Column  |              Type              | Collation | Nullable | Default
----------+--------------------------------+-----------+----------+---------
 userid   | integer                        |           | not null |
 username | character varying(64)          |           |          |
 ctime    | timestamp(6) without time zone |           |          |
Partition key: HASH (userid)
Indexes:
    "userinfo_pkey" PRIMARY KEY, btree (userid)
Number of partitions: 4 (Use \d+ to list them.)

查看子表,发现子表上也有了主键。

francs=> \d userinfo_p0
                         Table "francs.userinfo_p0"
  Column  |              Type              | Collation | Nullable | Default
----------+--------------------------------+-----------+----------+---------
 userid   | integer                        |           | not null |
 username | character varying(64)          |           |          |
 ctime    | timestamp(6) without time zone |           |          |
Partition of: userinfo FOR VALUES WITH (modulus 4, remainder 0)
Indexes:
    "userinfo_p0_pkey" PRIMARY KEY, btree (userid)

此主键为全局主键,子表间的主键之间不能有重复数据。

测试二: 创建索引

在父表上创建索引,如下

francs=> CREATE INDEX idx_userinfo_username ON userinfo USING BTREE(username);
CREATE INDEX

发现父表和子表上都创建了索引,如下。

francs=> \d userinfo
                          Table "francs.userinfo"
  Column  |              Type              | Collation | Nullable | Default
----------+--------------------------------+-----------+----------+---------
 userid   | integer                        |           | not null |
 username | character varying(64)          |           |          |
 ctime    | timestamp(6) without time zone |           |          |
Partition key: HASH (userid)
Indexes:
    "userinfo_pkey" PRIMARY KEY, btree (userid)
    "idx_userinfo_username" btree (username)
Number of partitions: 4 (Use \d+ to list them.)

francs=> \d userinfo_p1
                         Table "francs.userinfo_p1"
  Column  |              Type              | Collation | Nullable | Default
----------+--------------------------------+-----------+----------+---------
 userid   | integer                        |           | not null |
 username | character varying(64)          |           |          |
 ctime    | timestamp(6) without time zone |           |          |
Partition of: userinfo FOR VALUES WITH (modulus 4, remainder 1)
Indexes:
    "userinfo_p1_pkey" PRIMARY KEY, btree (userid)
    "userinfo_p1_username_idx" btree (username)

测试三: 创建外键

例如两张表,supplier_groups 和 supplier 分别用来存储供应商分组和供应商信, 如下。

CREATE TABLE supplier_groups(
    group_id    int4 PRIMARY KEY,
    group_name  text
);

CREATE TABLE suppliers (
    supplier_id    int4 PRIMARY KEY,
    supplier_name  text,
    group_id       int4 REFERENCES supplier_groups(group_id)
) PARTITION BY HASH (supplier_id);

创建子表

CREATE TABLE suppliers_p0 PARTITION OF suppliers FOR VALUES WITH(MODULUS 4, REMAINDER 0);
CREATE TABLE suppliers_p1 PARTITION OF suppliers FOR VALUES WITH(MODULUS 4, REMAINDER 1);
CREATE TABLE suppliers_p2 PARTITION OF suppliers FOR VALUES WITH(MODULUS 4, REMAINDER 2);
CREATE TABLE suppliers_p3 PARTITION OF suppliers FOR VALUES WITH(MODULUS 4, REMAINDER 3);

查看子表

查看子表,发现子表上也自动创建了外键。

francs=> \d suppliers_p0
               Table "francs.suppliers_p0"
    Column     |  Type   | Collation | Nullable | Default
---------------+---------+-----------+----------+---------
 supplier_id   | integer |           | not null |
 supplier_name | text    |           |          |
 group_id      | integer |           |          |
Partition of: suppliers FOR VALUES WITH (modulus 4, remainder 0)
Indexes:
    "suppliers_p0_pkey" PRIMARY KEY, btree (supplier_id)
Foreign-key constraints:
    "suppliers_group_id_fkey" FOREIGN KEY (group_id) REFERENCES supplier_groups(group_id)

总结

以上演示了 PostgreSQL 11 分区表在父表上创建索引、主键、外键后,子表会自动创建相应索引、主键、外键,相比10版本极大减少了分区表维护工作量。

参考

新书推荐

最后推荐和张文升共同编写的《PostgreSQL实战》,本书基于PostgreSQL 10 编写,共18章,重点介绍SQL高级特性、并行查询、分区表、物理复制、逻辑复制、备份恢复、高可用、性能优化、PostGIS等,涵盖大量实战用例!

购买链接:https://item.jd.com/12405774.html
_5_PostgreSQL_

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
13天前
|
运维 关系型数据库 Serverless
PolarDB产品使用问题之分区表是否支持2级分区
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
12天前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用问题之mysql迁移后查询不走索引了,该如何解决
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
13天前
|
运维 关系型数据库 分布式数据库
PolarDB产品使用问题之列存索引的原理是什么
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
27天前
|
存储 算法 数据处理
惊人!PolarDB-X 存储引擎核心技术的索引回表优化如此神奇!
【6月更文挑战第11天】PolarDB-X存储引擎以其索引回表优化技术引领数据库发展,提升数据检索速度,优化磁盘I/O,确保系统在高并发场景下的稳定与快速响应。通过示例代码展示了在查询操作中如何利用该技术高效获取结果。索引回表优化具备出色性能、高度可扩展性和适应性,为应对大数据量和复杂业务提供保障,助力企业与开发者实现更高效的数据处理。
|
10天前
|
运维 关系型数据库 分布式数据库
PolarDB产品使用问题之如何将普通表转换为分区表
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
12天前
|
SQL 关系型数据库 分布式数据库
PolarDB产品使用问题之如何查看SQL语句使用的是行索引还是列索引
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
12天前
|
SQL 关系型数据库 Serverless
PolarDB产品使用问题之分区表中,一般建议多少条记录创建一个分区
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
2月前
|
监控 关系型数据库 数据库
关系型数据库考虑索引的选择性
【5月更文挑战第20天】
36 4
|
1月前
|
关系型数据库 分布式数据库 数据库
PolarDB产品使用合集之表列存索引要怎么添加
PolarDB是阿里云推出的一种云原生数据库服务,专为云设计,提供兼容MySQL、PostgreSQL的高性能、低成本、弹性可扩展的数据库解决方案,可以有效地管理和优化PolarDB实例,确保数据库服务的稳定、高效运行。以下是使用PolarDB产品的一些建议和最佳实践合集。
|
1月前
|
关系型数据库 分布式数据库 数据库
PolarDB产品使用合集之优化器对索引的阈值一般是多少
PolarDB是阿里云推出的一种云原生数据库服务,专为云设计,提供兼容MySQL、PostgreSQL的高性能、低成本、弹性可扩展的数据库解决方案,可以有效地管理和优化PolarDB实例,确保数据库服务的稳定、高效运行。以下是使用PolarDB产品的一些建议和最佳实践合集。