2010-08-28 39 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功能和觸發器的例子可以提供,如果你想嘗試這...