如何创建PostgreSQL分区序列?

Foo*_*Bar 5 postgresql partitioning sequence

是否有一种简单的(即非hacky)和无竞争条件的方法来在PostgreSQL中创建分区序列.例:

在问题中使用正常序列:

| Project_ID | Issue |
| 1          | 1     |
| 1          | 2     |
| 2          | 3     |
| 2          | 4     |
Run Code Online (Sandbox Code Playgroud)

在问题中使用分区序列:

| Project_ID | Issue |
| 1          | 1     |
| 1          | 2     |
| 2          | 1     |
| 2          | 2     |
Run Code Online (Sandbox Code Playgroud)

Edm*_*und 3

我不相信有一种简单的方法可以像常规序列一样简单,因为:

  1. 序列仅存储一个数字流(下一个值等)。每个分区都需要一个。
  2. 序列具有绕过当前事务的特殊处理(以避免竞争条件)。如果不使用 dblink 等技巧,很难在 SQL 或 PL/pgSQL 级别复制此内容。
  3. DEFAULT 列属性可以使用简单的表达式或函数调用,例如nextval('myseq'); 但它无法引用其他列来通知函数该值应来自哪个流。

你可以做出一些有用的东西,但你可能不会认为它很简单。依次解决上述问题:

  1. 使用表存储所有分区的下一个值,其架构类似于multiseq (partition_id, next_val).
  2. 编写一个multinextval(seq_table, partition_id)执行如下操作的函数:

    1. 创建一个独立于当前事务的新事务(一种方法是通过 dblink;我相信其他一些服务器语言可以更轻松地做到这一点)。
    2. 锁定中提到的表seq_table
    3. partition_id使用递增的值更新分区 id 所在的行。(或者如果没有现有行,则插入值为 2 的新行。)
    4. 提交该事务并返回之前存储的 id(或 1)。
  3. 在项目表上创建一个插入触发器,使用调用来multinextval('projects_table', NEW.Project_ID)进行插入。

我自己没有使用整个计划,但我单独尝试了与每个步骤类似的方法。multinextval如果您想尝试此操作,可以提供函数和触发器的示例...