Postgresql
處理 PARTITION BY RANGE 上超出範圍的值
我有一個用於儲存事件的表,該表
timestamptz
使用PARTITION BY RANGE
.目前有 5 個分區,每個分區包含一個月的跨度,以 . 開頭
FOR VALUES FROM ('2018-01-01') TO ('2018-02-01')
和結尾FOR VALUES FROM ('2018-05-01') TO ('2018-06-01')
。大多數數據以線性和可預測的方式輸入。但是,事件由報告它們的應用程序使用,我確實必須允許隨時輸入過去的事件 - 這可能具有早於 的時間戳
2018-01-01
,甚至是未來的事件(例如,預計在未來的某個時間發生)。我計劃為過去的事件創建一個分區,該分區將持續超過一個月,因為不希望有太多這樣的事件。
我不確定對於尚不存在分區的未來事件來說,最好的方法是什麼。
有沒有辦法獲得我可以儲存在現有分區中的最小/最大值?如果沒有,我可以創建一個引用表來儲存這些值,但我寧願不必維護它。
我是否應該創建一個觸發器來檢查插入的每一行(似乎很昂貴)?我應該在插入時擷取錯誤並一次處理這些錯誤嗎?
上執行
PostgreSQL 10.3
。
有沒有辦法獲得我可以儲存在現有分區中的最小/最大值?
你還在評論中問:
您知道通過查詢獲取範圍的下限和上限的方法嗎?
我不知道有任何專門用於此特定目的的系統目錄資訊功能。但:
- 範圍分區基於內部繼承:
各個分區在後台通過繼承連結到分區表;
- 繼承樹儲存在
pg_inherits
:每個直接子表一個條目
- 分區邊界
pg_class.relpartbound
以內部格式 (pg_node_tree
) 儲存。- 系統目錄資訊功能
pg_get_expr(pg_node_tree, relation_oid)
可以:反編譯表達式的內部形式
我們可以從這組線索中建構一個查詢。基於手冊中的範圍分區範例:
SELECT i.inhrelid::regclass , partition_bound , split_part(partition_bound, '''', 2) AS lower_bound , split_part(partition_bound, '''', 4) AS upper_bound FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid , pg_get_expr(c.relpartbound, i.inhrelid) AS partition_bound WHERE inhparent = 'measurement'::regclass;
隱蔽 | partition_bound | 下限 | 上限 :------------------- | :----------------------------------------------- | :---------- | :---------- 測量_y2006m02 | 從 ('2006-02-01') 到 ('2006-03-01') 的值 | 2006-02-01 | 2006-03-01 測量_y2006m03 | 從 ('2006-03-01') 到 ('2006-04-01') 的值 | 2006-03-01 | 2006-04-01
db<>在這裡擺弄
限制:
- 基於單引號從字元串中提取下限和上限既便宜又髒。可能有一種更簡潔的方法可以直接從中提取價值
relpartbound
。- 只包括第一級繼承。您必須遞歸地遍歷圖形
pg_inherits
以涵蓋子分區。- 這建立在聲明性分區的幾個實現細節之上,這是 Postgres 10 的一個新特性。雖然我不認為這個查詢會因為下一個主要版本的變化而中斷,但它有可能發生。