支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.37. seg — 用於線段或浮點數區間的資料類型 #

此模組實作了一種資料類型 seg,用於表示線段或浮點數區間。seg 可以表示區間端點的不確定性,使其特別適用於表示實驗室測量。

此模組被認為是受信任的,也就是說,具有目前資料庫的 CREATE 權限的非超級使用者可以安裝它。

F.37.1. 基本原理 #

測量的幾何通常比數字連續體中的一個點更複雜。測量通常是該連續體的一段,具有些微模糊的界限。由於不確定性和隨機性,以及因為被測量的值可能自然是一個指示某些條件(例如蛋白質穩定性的溫度範圍)的區間,因此測量結果會以區間的形式呈現。

僅憑常識,將這些資料儲存為區間似乎更方便。實際上,在大多數應用程式中,它甚至更有效率。

沿著常識的方向,界限的模糊性表明使用傳統的數字資料類型會導致某些資訊的遺失。考慮一下:您的儀器讀數為 6.50,您將此讀數輸入資料庫。當您提取它時會得到什麼?注意

test=> select 6.50 :: float8 as "pH";
 pH
---
6.5
(1 row)

在測量的世界中,6.50 與 6.5 不同。有時可能非常重要。實驗者通常會記錄(並發布)他們信任的數字。 6.50 實際上是一個模糊區間,包含在一個更大且更模糊的區間 6.5 內,它們的中心點(可能)是它們共有的唯一特徵。我們絕對不希望如此不同的資料項目看起來相同。

結論?最好有一種特殊的資料類型,可以記錄具有任意可變精度的區間界限。可變是指每個資料元素記錄其自身的精度。

看看這個

test=> select '6.25 .. 6.50'::seg as "pH";
          pH
------------
6.25 .. 6.50
(1 row)

F.37.2. 語法 #

區間的外部表示形式是使用一個或兩個浮點數,並以範圍運算子 (.....) 連接而成。或者,它可以指定為中心點加上或減去一個偏差。也可以儲存可選的確定性指示符號 (<>~)。 (然而,所有內建運算子都會忽略確定性指示符號。)表格 F.27 概述了允許的表示形式;表格 F.28 顯示了一些範例。

表格 F.27 中,xydelta 表示浮點數。xy(而不是 delta)前面可以加上確定性指示符號。

表格 F.27. seg 外部表示形式

x 單一值(零長度區間)
x .. y xy 的區間
x (+-) delta x - deltax + delta 的區間
x .. 下界為 x 的開區間
.. x 上界為 x 的開區間

表 F.28. 有效的 seg 輸入範例

5.0 建立一個零長度的線段(如果可以這麼說,就是一個點)
~5.0 建立一個零長度的線段,並在資料中記錄 ~~ 會被 seg 操作忽略,但會被保留作為註解。
<5.0 在 5.0 處建立一個點。< 會被忽略,但會被保留作為註解。
>5.0 在 5.0 處建立一個點。> 會被忽略,但會被保留作為註解。
5(+-)0.3 建立一個區間 4.7 .. 5.3。請注意,(+-) 標記法不會被保留。
50 .. 所有大於或等於 50 的值
.. 0 所有小於或等於 0 的值
1.5e-2 .. 2E-2 建立一個區間 0.015 .. 0.02
1 ... 2 1...21 .. 21..2 相同(範圍運算子周圍的空格會被忽略)

由於 ... 運算子在資料來源中被廣泛使用,因此它被允許作為 .. 運算子的替代拼寫。 不幸的是,這會造成剖析上的模稜兩可:不清楚 0...23 中的上界是應解讀為 23 還是 0.23。 這透過要求 seg 輸入中所有數字的小數點前至少要有一位數字來解決。

作為健全性檢查,seg 拒絕下界大於上界的區間,例如 5 .. 2

F.37.3. 精確度 #

seg 值在內部儲存為 32 位元浮點數對。 這表示有效位數超過 7 位的數字將被截斷。

有效位數為 7 位或更少的數字會保留其原始精確度。 也就是說,如果您的查詢傳回 0.00,您可以確定尾隨的零不是格式化的產物:它們反映了原始資料的精確度。 前導零的數量不會影響精確度:值 0.0067 被認為只有 2 位有效位數。

F.37.4. 用法 #

seg 模組包含 seg 值的 GiST 索引運算子類別。 GiST 運算子類別支援的運算子如表 F.29所示。

表 F.29. Seg GiST 運算子

運算子

描述

seg << segboolean

第一個 seg 是否完全位於第二個的左側? [a, b] << [c, d] 如果 b < c 則為 true。

seg >> segboolean

第一個 seg 是否完全位於第二個的右側? [a, b] >> [c, d] 如果 a > d 則為 true。

seg &< segboolean

第一個 seg 是否未延伸到第二個的右側? [a, b] &< [c, d] 如果 b <= d 則為 true。

seg &> segboolean

第一個 seg 是否未延伸到第二個的左側? [a, b] &> [c, d] 如果 a >= c 則為 true。

seg = segboolean

兩個 seg 是否相等?

seg && segboolean

兩個 seg 是否重疊?

seg @> segboolean

第一個 seg 是否包含第二個?

seg <@ segboolean

第一個 seg 是否包含在第二個中?


除了上述運算子之外,表 9.1中顯示的常用比較運算子也適用於 seg 類型。 這些運算子首先比較 (a) 和 (c),如果它們相等,則比較 (b) 和 (d)。 在大多數情況下,這會產生相當不錯的排序,如果您想要將 ORDER BY 與此類型一起使用,這會很有用。

F.37.5. 注意事項 #

有關使用範例,請參閱迴歸測試 sql/seg.sql

(+-) 轉換為常規範圍的機制在確定邊界的有效位數時並不完全準確。 例如,如果產生的區間包含 10 的次方,它會向下邊界新增一個額外的數字

postgres=> select '10(+-)1'::seg as seg;
      seg
---------
9.0 .. 11             -- should be: 9 .. 11

R-tree 索引的效能很大程度上取決於輸入值的初始順序。 對 seg 欄位上的輸入表進行排序可能非常有幫助; 請參閱腳本 sort-segments.pl 以取得範例。

F.37.6. 致謝 #

原始作者:Gene Selkov, Jr. , Mathematics and Computer Science Division, Argonne National Laboratory。

我最感謝 Joe Hellerstein 教授 (https://dsf.berkeley.edu/jmh/),他闡明了 GiST 的要旨 (http://gist.cs.berkeley.edu/)。 我還要感謝所有 Postgres 開發人員,包括現在和過去的,他們使我能夠創造自己的世界並不受干擾地生活在其中。 我還要感謝 Argonne Lab 和美國能源部多年來對我的資料庫研究的忠實支持。

提交更正

如果您在文件中發現任何不正確、與特定功能的經驗不符或需要進一步澄清的內容,請使用此表單來報告文件問題。