ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# F.32\. seg 这个模块为定义线段和浮点类型的时间间隔提供了一种数据类型 `seg`, 这种数据类型由于可以代表不确定终点的区间,所以在做实验测量的时候特别有用。 ## F.32.1\. <--!Rationale-->原理 几何学测量要比测量连续的点复杂的多,测量出的结果通常是一些模糊限制的连续值 组成的区间值。这种区间的产生可能是由于测量出结果的不确定性,随机性,也可能 要测量的值本身就是以区间的形式作为条件的,如测量蛋白质稳定性的温度范围。 一般来说,用这个数据类型存储区间值比用双引号更方便。实际上,在大部分的应用 中这么使用也更有效率。 进一步说,传统数值类型存储数据可能对一些模糊限制的值产生偏差,你获取的会 值是6.50并且存入数据库,当你读出的时候会是什么,看下面例子: ``` test=> select 6.50 :: float8 as "pH"; pH --- 6.5 (1 row) ``` 在精确测量中,6.50和6.5代表的意思是不一样的,而且有时差异会很大。测量者 记下或者公布6.50代表了一个更大甚至更模糊的区间值,6.5只是代表了6.50的一 个中心点。像这种不同数据的同化表达是我们绝对不想看到的。 本章的特殊数据类型可以用来记录任意可变精度的间隔值,而且记录的每个数据都可以 使用自己的精度。 查看结果: ``` test=> select '6.25 .. 6.50'::seg as "pH"; pH ------------ 6.25 .. 6.50 (1 row) ``` ## F.32.2\. 语法 使用一个或者二个精度数代表一个区间,连接格式(`..`或 `...`)。另外也可以用值和偏移符号表示(`<`, `>` 或 `~`)。(正确的符号会被所有内建 的操作忽略。)表[Table F-24](#calibre_link-2301)和[Table F-25](#calibre_link-2302) 给出了区间表示的方法和一些例子。 在表[Table F-24](#calibre_link-2301)中 `_x_`, `_y_`和 `_delta_`代表双精度数。可以在`_x_`, `_y_`之前 添加正确的操作符。 **Table F-24\. `seg` External Representations** | `_x_` | 单个值(间隔为0) | |:--- |:--- | | `_x_` .. `_y_` | 区间`_x_` 到 `_y_` | | `_x_` (+-) `_delta_` | 区间 `_x_` - `_delta_` to `_x_` + `_delta_` | | `_x_` .. | `_x_`开区间无下限 | | `..` `_x_` | `_x_`开区间无上限 | **Table F-25\. Examples of Valid `seg` Input** | `5.0` | 零长度的区间(一个点) | |:--- |:--- | | `~5.0` | `~`作为一个标记存在,5.0的点和记录 | | `<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.32.3\. 精度 `seg`存储的值使用32-位的浮点数。精度不超过7位。 精度小于7位,保留本身的精度。换句话说如果你的返回值是0.00,那么这是数值本身带的精度 而不是格式化处理的。数值前的0不作为精度:值0.0067的精度被视为2。 ## F.32.4\. 使用 `seg`模块包含可以在 GiST索引中操作 `seg`数据类型值的类,该类支持表 [Table F-26](#calibre_link-2303)中的操作。 **Table F-26\. Seg GiST Operators** | 操作 | 描述 | | --- | --- | | `[a, b] << [c, d]` | [a,b]的范围完全在[c,d]的左侧。换句话说,b < c那么 [a,b] << [c, d] 为真,否则为假。 | | `[a, b] >> [c, d]` | [a,b]的范围全部在[c,d]的右侧。换句话说,a > d那么 [a,b] >> [c, d] 为真,否则为假。 | | `[a, b] &< [c, d]` | 左包含,或者解读为取值范围不超过右边,b <= d时为真。 | | `[a, b] &> [c, d]` | 右包含,或者解读为取值范围不超过左边,a >= c时为真。 | | `[a, b] = [c, d]` | [a, b]和[c, d]相同,当a=c并且b=d时为真。 | | `[a, b] && [c, d]` | [a, b]和[c, d]重叠部分 | | `[a, b] @> [c, d]` | [a, b]包含[c, d],意味着 a <= c并且 b >= d。 | | `[a, b] <@ [c, d]` | [a, b]被[c, d]包含,意味着 a >= c and b <= d。 | PostgresSQL 8.2之前的版本中,`@>` 和`<@`分别用`@`和`~`表示。 但那种表示方式会在将来完全被替代,所以不赞成使用。注意旧的名称会随着代表几何的数据类型转换为惯例的格式。 提供标准的B-tree操作,例如 | 操作 | 描述 | | --- | --- | | `[a, b] < [c, d]` | 小于 | | `[a, b] > [c, d]` | 大于 | 这些操作除了做排序以外没有别的用处,首先是(a)和(c)比较大小,如果 相等在比较(b)和(d)。如果使用这种类型排序,得到的的结果在大多数情 况下是合理的。 ## F.32.5\. 注意 使用例子,参看回归测试 `sql/seg.sql`。 使用 `(+-)`机制转换数字的时候可能得到不确定的精度。举个例子他可能 为较低的边界值增加额外的精度: ``` postgres=> select '10(+-)1'::seg as seg; seg --------- 9.0 .. 11 -- 应该为: 9 .. 11 ``` R-tree索引的性能很大程度上依赖初始输入值的排序。在输入表的`seg`类型列 上排序可能是非常有效果的;参考脚本 `sort-segments.pl`。 ## F.32.6\. 感谢 原作者:Gene Selkov, Jr. `<[selkovjr@mcs.anl.gov](mailto:selkovjr@mcs.anl.gov)>`,数学与计算机科学部,阿贡国家实验室。 感谢Joe Hellerstein教授 ([http://db.cs.berkeley.edu/jmh/](http://db.cs.berkeley.edu/jmh/))阐明的思想 ([http://gist.cs.berkeley.edu/](http://gist.cs.berkeley.edu/))。感谢所有 Postgres开发者,使我可以站在巨人的肩膀上。 感谢阿贡实验室和美国能源部多年的忠实支持我的数据库的研究。