2010-08-28 67 views
5

在PostgreSQL中是否有一个简单的(即非哈希)和竞态条件自由的方式来创建分区序列。例如:如何创建PostgreSQL分区序列?

使用争议中的正常序列:

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

使用争议中的分区顺序:

| Project_ID | Issue | 
| 1   | 1  | 
| 1   | 2  | 
| 2   | 1  | 
| 2   | 2  | 
+0

我很高兴知道是否有一个优雅的解决方案,这个问题。这里的解决方案:http://stackoverflow.com/questions/4672629/postgresql-company-id-based-sequence是不错,但它会是交易安全吗? – Atorian 2011-04-13 19:26:34

回答

1

我不相信有是作为常规序列容易的简单方法,因为:

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

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

  1. 使用表来存储所有分区的下一个值,其模式为multiseq (partition_id, next_val)
  2. multinextval(seq_table, partition_id)函数,它像下面这样:这样做的

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

我自己并没有使用这整个计划,但我已经尝试了类似于每个步骤的东西。 multinextval功能和触发器的例子可以提供,如果你想尝试这...