如何创建PostgreSQL分区序列?

时间:2010-08-28 15:26:28

标签: postgresql sequence partitioning

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

在问题中使用正常序列:

| Project_ID | Issue |
| 1          | 1     |
| 1          | 2     |
| 2          | 3     |
| 2          | 4     |

在问题中使用分区序列:

| Project_ID | Issue |
| 1          | 1     |
| 1          | 2     |
| 2          | 1     |
| 2          | 2     |

1 个答案:

答案 0 :(得分:2)

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

  1. 序列仅存储一个数字流(下一个值等)。你想要每个分区一个。
  2. 序列具有绕过当前事务的特殊处理(以避免竞争条件)。如果不使用像dblink这样的技巧,很难在SQL或PL / pgSQL级别复制它。
  3. DEFAULT列属性可以使用简单表达式或函数调用,如nextval('myseq');但它不能引用其他列来通知函数该值应该来自哪个流。
  4. 你可以创造有用的东西,但你可能不会认为它很简单。依次解决上述问题:

    1. 使用表格存储所有分区的下一个值,其格式为multiseq (partition_id, next_val)
    2. 编写一个multinextval(seq_table, partition_id)函数,执行以下操作:

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

    4. 我自己没有使用过整个计划,但我已经尝试过类似于每个步骤的内容。如果您想尝试此操作,可以提供multinextval函数和触发器的示例...