支援的版本:目前 (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...2, 或 1 .. 2, 或 1..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 時為真。

seg >> segboolean

第一個 seg 是否完全位於第二個的右側? [a, b] >> [c, d] 在 a > d 時為真。

seg &< segboolean

第一個 seg 是否沒有延伸到第二個的右側? [a, b] &< [c, d] 在 b <= d 時為真。

seg &> segboolean

第一個 seg 是否沒有延伸到第二個的左側? [a, b] &> [c, d] 在 a >= c 時為真。

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

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

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

R 樹索引的效能很大程度上取決於輸入值的初始順序。 在 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 和美國能源部多年來對我的資料庫研究的忠實支持。

提交更正

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