此模块实现了表示直线段或浮点数区间的 seg
数据类型。 seg
可以表示区间端点的模糊性,使其特别适用于表示实验室测量值。
此模块被认为是““可信””,也就是说,它可以由具有在当前数据库上拥有 CREATE
权限的非超级用户安装。
测量中的几何通常比数值连续统一体中的点更复杂。测量通常是该连续统一体中具有某种模糊限制的线段。测量结果以区间的形式出现,这既是因为模糊性和随机性,也因为待测量值在本质上可能是区间,表示某种条件,例如蛋白质稳定性的温度范围。
使用常识可知,以区间而非数字对的形式存储此类数据更加方便。在实践中,它甚至在大多数应用程序中都更有效。
在常识的指导下,模糊限制表明使用传统的数字数据类型会导致一定程度的信息丢失。考虑这一点:仪器读数为 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.27 提供了允许表示形式的概述;表 F.28 显示了一些示例。
在表 F.27中,x
、y
和 delta
表示浮点数。x
和 y
可以有确定性指示符,但 delta
不可以。
表 F.27. seg
外部表示形式
|
单个值(零长度区间) |
|
从 x 到 y 的区间 |
|
间隔从 x - delta 到 x + delta |
|
下限为 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
。
seg
值在内部存储为 32 位浮点数的成对数字。这意味着小数位多于 7 位的数字会被截断。
小数位少于或等于 7 位的数字将保留其原始精度。也就是说,如果您的查询返回 0.00,您将可以确定尾随零不是格式调整的人工制品:它们反映原始数据的精度。前导零的位数不影响精度:数字 0.0067 被认为只有 2 个小数位。
seg
模块包括一个 seg
值的 GiST 索引操作符类。 GiST 操作符类支持的操作符显示在 表 F.29 中。
表 F.29. Seg GiST 操作符
操作符 描述 |
---|
第一个 |
第一个 |
第一个 |
第一个 |
两个 |
两个 |
第一个 |
第一个 |
除了上述运算符之外,表 9.1 中所示的常用比较运算符也可用于 seg
类型。这些运算符首先比较 (a) 到 (c),如果它们相等,则比较 (b) 到 (d)。在大多数情况下,这会导致相当不错的排序,在使用这种类型时,如果您想使用 ORDER BY,这会很有用。
有关使用示例,请参见回归测试 sql/seg.sql
。
将 (+-)
转换为常规范围的机制在确定边界的有效数字位数时并不完全准确。例如,如果结果区间包含十的幂,它将为较低边界添加一个额外的数字
postgres=> select '10(+-)1'::seg as seg; seg --------- 9.0 .. 11 -- should be: 9 .. 11
R 树索引的性能在很大程度上取决于输入值的初始顺序。在 seg
列上对输入表进行排序可能非常有帮助;有关示例,请参见脚本 sort-segments.pl
。
原始作者:Gene Selkov, Jr. <[email protected]>
, 数学与计算机科学分部,Argonne 国家实验室。
首先我要感谢 Prof. Joe Hellerstein (https://dsf.berkeley.edu/jmh/),他阐明了 GiST (http://gist.cs.berkeley.edu/) 的要旨。我还要感谢所有过去的和现在的 Postgres 开发者,因为他们让我能够创造我自己的世界,并安然无恙地生活其中。我还要感谢 Argonne 实验室和美国能源部,因为他们多年来一直忠实地支持我的数据库研究。