文本处理与多维数据类型
文本处理与多维数据类型
本文件包含模块:citext(大小写不敏感字符串)、cube(多维立方体)、dblink(跨库连接)、dict_int/dict_xsyn(词典模板)、earthdistance(地球距离)。
citext
citext模块提供了一种大小写不敏感的字符串类型:citext。它在比较值时内部调用的是lower。除此之外,它的行为几乎与text完全相同。
提示:可考虑使用nondeterministic collations来代替这个模块.它们可被用于大小写不敏感的比较,不区分重音的比较,以及其他组合,并且他们可以正确的处理更多Unicode特殊情况。
此模块被视为"可信(trusted)",也就是说,它可以由当前数据库上具有 CREATE 权限的非超级用户来安装。
基本原理
在Halo中做大小写不敏感匹配的标准方法曾经是在比较值时使用lower函数,例如:
SELECT * FROM tab WHERE lower(col) = LOWER(?);
这工作得比较好,但是有一些缺点:
• 它让你的 SQL 语句冗长,并且你必须总是要记住在列和查询值上使用lower。
• 它不会使用一个索引,除非你使用lower创建一个函数索引。
• 如果你声明一个列为UNIQUE或PRIMARY KEY,隐式生成的索引是大小写敏感的。因此,它对于大小写不敏感的搜索是没有用处的,并且它不会强制大小写不敏感的唯一性。
citext数据类型允许你在 SQL 查询中消除对lower的调用,并且允许一个主键是大小写无关的。就和text一样,citext是区域相关的,这意味着大写和小写字符的匹配依赖于数据库LC_CTYPE设置的规则。此外,这种行为和在查询中使用lower是一样的。但是因为它是由数据类型以透明的方式完成的,你不需要记住在你的查询中做任何特殊的事情。
如何使用它
这里是一个简单的用法示例:
test=# CREATE TABLE users (
test(# nick CITEXT PRIMARY KEY,
test(# pass TEXT NOT NULL
test(# );
CREATE TABLE
test=# INSERT INTO users VALUES ( 'larry', sha256(random()::text::bytea) );
INSERT 0 1
test=# INSERT INTO users VALUES ('Tom', sha256(random()::text::bytea) );
INSERT 0 1
test=# INSERT INTO users VALUES ( 'Damian', sha256(random()::text::bytea) );
INSERT 0 1
test=# INSERT INTO users VALUES ( 'NEAL', sha256(random()::text::bytea) );
INSERT 0 1
test=# INSERT INTO users VALUES ( 'Bjørn', sha256(random()::text::bytea) );
INSERT 0 1
test=# SELECT * FROM users WHERE nick = 'Larry';
nick | pass
-------+------------------------------------------------------------------
Larry | \\xe7dee32074f92f34e4e838c1ba66a3e9e8cb8729dcebfcaa92edb08614666fab
(1 row)
即使nick列被设置为larry而查询是Larry,SELECT语句也将只返回一个元组。
串比较行为
citext执行比较时先将每一个串转换成小写形式(调用lower)然后正常地比较结果。因此,如果两个串通过lower产生相同的结果,它们就被认为是相等。
为了尽可能接近地模拟一种大小写不敏感的排序规则,一些串处理操作符和函数有citext相关的版本。例如,当应用到citext时,正则表达式操作符~和~*会展现出相同的行为:它们都以大小写不敏感的方式匹配。!~和!~*也是一样,以及LIKE操作符~~和~~*,以及!~~和!~~*。如果你想以大小写敏感的方式匹配,你可以把该操作符的参数设置成text。
相似地,如果下列函数的参数是citext,它们会以大小写不敏感的方式执行匹配:
• regexp_match()
• regexp_matches()
• regexp_replace()
• regexp_split_to_array()
• regexp_split_to_table()
• replace()
• split_part()
• strpos()
• translate()
对于 regexp 函数,如果你想要以大小写敏感的方式匹配,你可以指定"c"标志来强制大小写敏感的匹配。否则,如果你想要大小写敏感的行为,你必须在使用这些函数之前设置到text。
限制
• citext的大小写折叠行为取决于你的数据库的LC_CTYPE设置。因此它比较值是在数据库被创建时决定的。在 Unicode 标准定义的术语中没有真正的大小写不敏感。实际上,它的含义是,只要自己对你的排序规则满意,你就应该对citext的比较满意。如果在你的数据库中存储有不同语言的数据,排序规则是用于一种语言时,另一种语言的用户可能会发现他们的查询结果并不是所期待的。
•你可以为citext列或数据值附加一个COLLATE说明。当前,在比较大小写折叠过的字符串时,citext操作符将尊重一种非默认的COLLATE说明,但是最初到小写形式的折叠是根据数据库的 LC_CTYPE设置完成的(就是说,尽管给出了COLLATE "default")。这可能在未来的发行中被改变,这样两步都能遵循输入的COLLATE说明。
• citext的效率不如text,因为操作符函数和 B 树比较函数必须创建数据的拷贝,并且将它转换为小写形式来进行比较。此外,只有text可以支持B树重复数据删除。不过,在进行大小写不敏感的匹配时,citext比使用lower的效率要略高。
• 如果你在某些环境下需要以大小写敏感的方式比较数据,在另一些环境下需要以大小写不敏感的方式比较数据,citext就帮不上什么忙。标准的答案是使用text类型,在你需要以大小写不敏感的方式比较时手工使用lower函数。如果大小写不敏感的比较需求不频繁,这会工作得不错。如果你大部分时间需要大小写不敏感的行为,考虑将数据存储为citext并且在进行大小写敏感比较时显式地将列造型为text。不管在那种情况下,你都需要两个索引来让两种类型的搜索更快。
• 包含citext操作符的模式必须在当前的search_path(通常是public)中。如果它不在搜索路径中,普通的大小写敏感的text操作符将会取而代之。
• 比较小写字符串的方法不能正确处理一些Unicode特殊情况,例如当一个大写字母与两个小写字母相等时。因此Unicode区分了case mapping 和 case folding。
cube
这个模块实现了一种数据类型cube来表示多维立方体。
此模块被视为"trusted",也就是说,它可以在当前数据库上具有 CREATE 权限的非超级用户安装。
语法
表 D.2展示了cube类型有效的外部表示。x、y等表示浮点数。
表 D.2立方体外部表示
------------------------------- ----------------------------------------------------------
外部语法 含义
x 一个一维点(或者长度为零的一维区间)
\(x\) 同上
x1,x2,\...,xn n-维空间中的一个点,内部表示为一个零容积立方体
(x1,x2,\...,xn) 同上
(x),(y) 开始于x并且结束于y的一个一维区间,反之亦然。顺序并不重要
\[(x),(y)\] 同上
(x1,\...,xn),(y1,\...,yn) 一个 n-维立方体,用它的对角顶点对表示
\[(x1,\...,xn),(y1,\...,yn)\] 同上
------------------------------- ----------------------------------------------------------
一个立方体的对角录入的顺序无关紧要。如果需要创建一种统一的"左下 --- 右上"的内部表示,cube函数会自动地交换值。当角重合时,cube只存储一个角和一个"is point"标志,这样避免浪费空间。
输入中的空白空间会被忽略,因此[(x),(y)]与[ ( x ), ( y ) ]相同。
精度
值在内部被存储为 64 位浮点数。这意味着超过 16 位有效位的数字将被截断。
用法
表 D.3展示了为类型cube提供的专用的操作符。
表 D.3. 立方体操作符
操作符/描述:
cube && cube → boolean:立方体是否有重叠?cube @> cube → boolean:第一个立方体是否包含第二个立方体?cube <@ cube → boolean:第一个立方体是否包含在第二个立方体里面?cube -> integer → float8:提取立方体的第 n个坐标,(从1开始计数)。cube ~> integer → float8:提取立方体的第 n个坐标,以下列方式计数: n = 2 * k - 1 表示第k个维度的下限, n = 2 * k 表示第k个维度的上限。 负的n表示相应正坐标的倒数值。此操作符专为 KNN-GiST 支持而设计。cube <-> cube → float8:计算两个立方体之间的欧几里德距离.cube <#> cube → float8:计算两个立方体之间的直线(L-1 度量)距离。cube <=> cube → float8:计算两个立方体之间的切比雪夫(L-inf 度量)距离.
这些操作符首先比较第一个坐标,如果它们相等再比较第二个坐标等等。 它们主要为支持cube的 b树索引操作符类而存在,这类操作符对支持cube列上的 UNIQUE 约束等很有用。否则,这种排序没有太大的实际作用。
cube模块也为cube值提供了一个 GiST 索引操作符类。cube GiST 索引可以被用于在WHERE子句中通过=、&&、@>以及<@操作符来搜索值。
此外,cube GiST 索引可以被用在ORDER BY子句中通过度量操作符<->、<#>和<=>来查找最近邻。例如,3-D 点(0.5, 0.5, 0.5)的最近邻可以用下面的查询很快地找到:
SELECT c FROM test ORDER BY c <-> cube(array[0.5,0.5,0.5]) LIMIT 1;
也可以用这种方式使用~>操作符来高效地检索通过选定坐标排序后的前几个值。例如,可以用下面的查询得到通过第一个坐标(左下角)升序排列后的前几个立方体:
SELECT c FROM test ORDER BY c ~> 1 LIMIT 5;
以及得到通过右上角第一个坐标降序排列后的 2-D 立方体:
SELECT c FROM test ORDER BY c ~> 3 DESC LIMIT 5;
表 D.4展示了可用的函数。
表 D.4. 立方体函数
函数/描述:/示例:
cube ( float8 ) → cube:制作一个一维立方体,其两个坐标都是相同的。 cube(1) → (1)cube ( float8, float8 ) → cube:制作一个一维立方体。 cube(1,2) → (1),(2)cube ( float8[] ) → cube:使用数组定义的坐标制作一个零值的立方体 cube(ARRAY[1,2,3]) → (1, 2, 3)cube ( float8[], float8[] ) → cube:用由两个数组定义的右上和左下坐标制造一个立方体,两个数组必等长。 cube(ARRAY[1,2], ARRAY[3,4]) → (1, 2),(3, 4)cube ( cube, float8 ) → cube:在一个现有的立方体上增加一维来制造一个新立方体,对新坐标的各个端点都采用相同的值。这可以用于从计算得到的值逐渐地构建立方体。 cube('(1,2),(3,4)'::cube, 5) → (1, 2, 5),(3, 4, 5)cube ( cube, float8, float8 ) → cube:在一个现有的立方体上增加一维来制造一个新立方体。这可以用于计算得到的值逐渐地构建立方体。 cube('(1,2),(3,4)'::cube, 5, 6) → (1, 2, 5),(3, 4, 6)cube_dim ( cube ) → integer:返回该立方体的维数。 cube_dim('(1,2),(3,4)') → 2cube_ll_coord ( cube, integer ) → float8:返回一个立方体的左下角的第 n个坐标值 cube_ll_coord('(1,2),(3,4)', 2) → 2cube_ur_coord ( cube, integer ) → float8:返回一个立方体的右上角的第n个坐标值 cube_ur_coord('(1,2),(3,4)', 2) → 4cube_is_point ( cube ) → boolean:如果一个立方体是一个点则返回真,也就是两个定义点相同。 cube_is_point(cube(1,1)) → tcube_distance ( cube, cube ) → float8:返回两个立方体之间的距离。如果两个都是点,这就是普通距离函数。 cube_distance('(1,2)', '(3,4)') → 2.8284271247461903cube_subset ( cube, integer[] ) → cube:从一个现有的立方体制造一个新立方体,使用来自于一个数组的维索引列表。它可以被用来抽取一个单一维度的端点,或者它可以被用来去除维度,或者按照需要对它们重新排序。 cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2]) → (3),(7) cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]) → (5, 3, 1, 1),(8, 7, 6, 6)cube_union ( cube, cube ) → cube:产生两个立方体的并集。 cube_union('(1,2)', '(3,4)') → (1, 2),(3, 4)cube_inter ( cube, cube ) → cube:产生两个立方体的交集。 cube_inter('(1,2)', '(3,4)') → (3, 4),(1, 2)cube_enlarge ( c cube, r double, n integer ) → cube:用一个指定的半径r在至少n个维度上增加立方体的尺寸。如果该半径是负值,则该立方体会收缩。所有已定义的维度都会按照半径r被改变。左下坐标按照 r被减小并且右上坐标按照 r被增加。如果一个左下坐标被增加得超过对应的右上坐标(这只会发生在r < 0 时),则两个坐标会被设置为它们的均值。如果n大于已定义的维度数并且该立方体被增加(r > 0), 则额外的维度会被加入以让维度数达到n,对于额外的坐标将使用 0 作为初始值。这个函数可用来创建围绕一个点的边界框以搜索临近点。 cube_enlarge('(1,2),(3,4)', 0.5, 3) → (0.5, 1.5, -0.5),(3.5, 4.5, 0.5)
默认值
下面的并:
test=# select cube_union('(0,5,2),(2,3,1)', '0');
cube_union
---------------------
(0, 0, 0),(2, 5, 2)
(1 row)
不会与常识矛盾,下面的交也不会
test=# select cube_inter('(0,-1),(1,1)', '(-2),(2)');
cube_inter
---------------
(0, 0),(1, 0)
(1 row)
在所有不同维度立方体的二元操作中,假定低纬度的那一个要做投影,即为字符串表示中被省略的坐标取零。上面的例子等同于:
cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)');
cube_inter('(0,-1),(1,1)','(-2,0),(2,0)');
下列包含谓词使用点语法,不过实际上第二个参数在内部被表示为一个盒子。这种语法让我们不必定义一种单独的点类型以及用于谓词的函数。
test=# select cube_contains('(0,0),(1,1)', '0.5,0.5');
cube_contains
---------------
t
(1 row)
注解
为了不容易出问题,对于立方体的维度数有 100 的限制。如果你想要更大的立方体,可以在cubedata.h中修改。
dblink
dblink是一个支持在一个数据库会话中连接到其他数据库的模块。
还可以看看postgres_fdw,它以一种更现代和更加兼容标准的架构提供了相同的功能。
dblink_connect
dblink_connect --- 打开一个到远程数据库的持久连接
大纲
dblink_connect(text connstr) 返回 text
dblink_connect(text connname, text connstr) 返回 text
描述
dblink_connect()建立一个到远程数据库的连接。要联系的服务器和数据库通过一个标准的libpq连接串来标识。可以选择将一个名字赋予给该连接。多个命名的连接可以被一次打开,但是一次只允许一个未命名连接。连接将会持续直到被关闭或者数据库会话结束。
连接串也可以是一个现存外部服务器的名字。在使用外部服务器时,我们推荐使用外部数据包装器dblink_fdw。见下面的例子,以及CREATE SERVER和CREATE USER MAPPING。
参数
connname
要用于这个连接的名字。如果被忽略,将打开一个未命名连接并且替换掉任何现有的未命名连接。
connstr
libpq-风格的连接信息串,例如 hostaddr=127.0.0.1 port=5432 dbname=mydb
user=postgres password=mypasswd。可以是一个外部服务器的名字。
返回值
返回状态,它总是OK(任何错误会导致该函数抛出一个错误,而不是返回)。
注解
如果不可信用户能够访问一个没有采用安全方案使用模式的数据库,应该在开始每个会话时,从search_path中移除公共可写的方案。例如,可以把options=-csearch_path=增加到connstr。这种考虑不是特别针对dblink,它适用于每一种执行任意SQL命令的接口。
只有超级用户能够使用dblink_connect来创建无口令认证连接。如果非超级用户需要这种能力,使用dblink_connect_u。
选择包含等号的连接名是不明智的,因为这会产生与在其他dblink函数中的连接信息串混淆的风险。
例子
SELECT dblink_connect('dbname=postgres options=-csearch_path=');
dblink_connect
----------------
OK
(1 row)
SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path=');
dblink_connect
----------------
OK
(1 row)
-- FOREIGN DATA WRAPPER functionality
-- Note: local connection must require password authentication for this to work
properly
-- Otherwise, you will receive the following error from dblink_connect():
-- ERROR: password is required
-- DETAIL: Non-superuser cannot connect if the server does not request a
password.
-- HINT: Target server's authentication method must be changed.
CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw OPTIONS (hostaddr '127.0.0.1', dbname 'contrib_regression');
CREATE USER regress_dblink_user WITH PASSWORD 'secret';
CREATE USER MAPPING FOR regress_dblink_user SERVER fdtest OPTIONS (user 'regress_dblink_user', password 'secret');
GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user;
GRANT SELECT ON TABLE foo TO regress_dblink_user;
\\set ORIGINAL_USER :USER
\\c - regress_dblink_user
SELECT dblink_connect('myconn', 'fdtest');
dblink_connect
----------------
OK
(1 row)
SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]);
a | b | c
----+---+---------------
0 | a | {a0,b0,c0}
1 | b | {a1,b1,c1}
2 | c | {a2,b2,c2}
3 | d | {a3,b3,c3}
4 | e | {a4,b4,c4}
5 | f | {a5,b5,c5}
6 | g | {a6,b6,c6}
7 | h | {a7,b7,c7}
8 | i | {a8,b8,c8}
9 | j | {a9,b9,c9}
10 | k | {a10,b10,c10}
(11 rows)
\\c - :ORIGINAL_USER
REVOKE USAGE ON FOREIGN SERVER fdtest FROM regress_dblink_user;
REVOKE SELECT ON TABLE foo FROM regress_dblink_user;
DROP USER MAPPING FOR regress_dblink_user SERVER fdtest;
DROP USER regress_dblink_user;
DROP SERVER fdtest;
**dblink_connect_u**
dblink_connect_u --- 不安全地打开一个到远程数据库的持久连接
大纲
dblink_connect_u(text connstr) 返回 text
dblink_connect_u(text connname, text connstr) 返回 text
描述
dblink_connect_u()和dblink_connect()一样,不过它将允许非超级用户使用任意认证方式来连接。
如果远程服务器选择了一种不涉及口令的认证方式,那么可能发生模仿以及后续的扩大权限,因为该会话看起来像由运行Halo的用户发起的。此外,即使远程服务器不要求一个口令,也可能从服务器环境提供该口令,例如一个属于服务器用户的~/.pgpass文件。这带来的不只是模仿的风险,而且还有将口令暴露给不可信的远程服务器的风险。因此,dblink_connect_u()最初是用所有从PUBLIC撤销的特权安装的,这让它只能被超级用户调用。在某些情况中,为dblink_connect_u()授予EXECUTE权限给可信的指定用户是合适的,但是必须小心。我们也推荐任何属于服务器用户的~/.pgpass文件不能包含任何指定了一个通配符主机名的记录。
详见dblink_connect()。
dblink_disconnect
dblink_disconnect --- 关闭一个到远程数据库的持久连接
大纲
dblink_disconnect() 返回 text
dblink_disconnect(text connname) 返回 text
描述
dblink_disconnect()关闭一个之前被dblink_connect()打开的连接。不带参数的形式关闭一个未命名连接。
参数
connname
要被关闭的命名连接的名字。
返回值
它总是OK(因为任何错误会导致该函数抛出一个错误而不是返回)。
例子
SELECT dblink_disconnect();
dblink_disconnect
-------------------
OK
(1 row)
SELECT dblink_disconnect('myconn');
dblink_disconnect
-------------------
OK
(1 row)
**dblink**
dblink --- 在一个远程数据库中执行一个查询
大纲
dblink(text connname, text sql [, bool fail_on_error]) 返回记录集
dblink(text connstr, text sql [, bool fail_on_error]) 返回记录集
dblink(text sql [, bool fail_on_error]) 返回记录集
描述
dblink在一个远程数据库中执行一个查询(通常是一个SELECT,但是也可以是任意返回行的SQL 语句)。
当给定两个text参数时,第一个被首先作为一个持久连接的名称进行查找;如果找到,该命令会在该连接上被执行。如果没有找到,第一个参数被视作一个用于dblink_connect的连接信息字符串,并且被指出的连接只是在这个命令的持续期间被建立。
参数
connname
要使用的连接名。忽略这个参数将使用未命名连接。
connstr
如之前为dblink_connect所描述的一个连接信息字符串。
sql
你希望在远程数据库中执行的 SQL 查询,例如select * from foo。
fail_on_error
如果为真(忽略时的默认值),那么在连接的远端抛出的一个错误也会导致本地抛出一个错误。如果为假,远程错误只在本地被报告为一个 NOTICE,并且该函数不反回行。
返回值
该函数返回查询产生的行。因为dblink能与任何查询一起使用,它被声明为返回record,而不是指定任意特定的列集合。这意味着你必须指定在调用的查询中所期待的列集合 --- 否则Halo将不知道会得到什么。这里是一个例子:
SELECT * FROM dblink('dbname=mydb options=-csearch_path=',
'select proname, prosrc from pg_proc')
AS t1(proname name, prosrc text)
WHERE proname LIKE 'bytea%';
FROM子句的"alias"部分必须指定函数将返回的列名及类型(在一个别名中指定列名实际上是标准 SQL 语法,但是指定列类型是一种Halo扩展)。这允许系统在尝试执行该函数之前就理解*将展开成什么,以及WHERE子句中的proname指的什么。在运行时,如果来自远程数据库的实际查询结果和FROM子句中显示的列数不同,将会抛出一个错误。不过,列名不需要匹配,并且dblink并不坚持精确地匹配类型。只要被返回的数据字符串是FROM子句中声明的列类型的合法输入,它就将会成功。
注解
一种将预定义查询用于dblink的方便方法是创建一个视图。这允许列类型信息被埋藏在该视图中,而不是在每一个查询中都拼写出来。例如:
test=# CREATE VIEW myremote_pg_proc AS
test-# SELECT *
test-# FROM dblink('dbname=postgres options=-csearch_path=',
test(# 'select proname, prosrc from pg_proc')
test-# AS t1(proname name, prosrc text);
CREATE VIEW
SELECT * FROM myremote_pg_proc WHERE proname LIKE 'bytea%';
例子
SELECT * FROM dblink('dbname=postgres options=-csearch_path=',
'select proname, prosrc from pg_proc')
AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
proname | prosrc
------------+------------
byteacat | byteacat
byteaeq | byteaeq
bytealt | bytealt
byteale | byteale
byteagt | byteagt
byteage | byteage
byteane | byteane
byteacmp | byteacmp
bytealike | bytealike
byteanlike | byteanlike
byteain | byteain
byteaout | byteaout
(12 rows)
SELECT dblink_connect('dbname=postgres options=-csearch_path=');
dblink_connect
----------------
OK
(1 row)
SELECT * FROM dblink('select proname, prosrc from pg_proc')
AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
proname | prosrc
------------+------------
byteacat | byteacat
byteaeq | byteaeq
bytealt | bytealt
byteale | byteale
byteagt | byteagt
byteage | byteage
byteane | byteane
byteacmp | byteacmp
bytealike | bytealike
byteanlike | byteanlike
byteain | byteain
byteaout | byteaout
(12 rows)
SELECT dblink_connect('myconn', 'dbname=regression options=-csearch_path=');
dblink_connect
----------------
OK
(1 row)
SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc')
AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
proname | prosrc
------------+------------
bytearecv | bytearecv
byteasend | byteasend
byteale | byteale
byteagt | byteagt
byteage | byteage
byteane | byteane
byteacmp | byteacmp
bytealike | bytealike
byteanlike | byteanlike
byteacat | byteacat
byteaeq | byteaeq
bytealt | bytealt
byteain | byteain
byteaout | byteaout
(14 rows)
**dblink_exec**
dblink_exec --- 在一个远程数据库中执行一个命令
大纲
dblink_exec(text connname, text sql [, bool fail_on_error]) returns text
dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text
dblink_exec(text sql [, bool fail_on_error]) returns text
描述
dblink_exec在一个远程数据库中执行一个命令(也就是,任何不返回行的 SQL 语句)。
当给定两个text参数时,第一个被首先作为一个持久连接的名称进行查找;如果找到,该命令会在该连接上被执行。如果没有找到,第一个参数被视作一个用于dblink_connect的连接信息字符串,并且被指出的连接只是在这个命令的持续期间被建立。
参数
connname
要使用的连接名。忽略这个参数将使用未命名连接。
connstr
如之前为dblink_connect所描述的一个连接信息字符串。
sql
你希望在远程数据库中执行的 SQL 命令,例如insert into foo values(0, 'a',
'{"a0","b0","c0"}')。
fail_on_error
如果为真(忽略时的默认值),那么在连接的远端抛出的一个错误也会导致本地抛出一个错误。如果为假,远程错误只在本地被报告为一个 NOTICE,并且该函数的返回值被设置为ERROR。
返回值
返回状态,可能是命令的状态字符串或ERROR。
例子
SELECT dblink_connect('dbname=dblink_test_standby');
dblink_connect
----------------
OK
(1 row)
SELECT dblink_exec('insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');');
dblink_exec
-----------------
INSERT 943366 1
(1 row)
SELECT dblink_connect('myconn', 'dbname=regression');
dblink_connect
----------------
OK
(1 row)
SELECT dblink_exec('myconn', 'insert into foo values(21, ''z'',
''{"a0","b0","c0"}'');');
dblink_exec
------------------
INSERT 6432584 1
(1 row)
SELECT dblink_exec('myconn', 'insert into pg_class values (''foo'')',false);
NOTICE: sql error
DETAIL: ERROR: null value in column "relnamespace" violates not-null
constraint
dblink_exec
-------------
ERROR
(1 row)
**dblink_open**
dblink_open --- 在一个远程数据库中打开一个游标
大纲
dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text
dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text
描述
dblink_open()在一个远程数据库中打开一个游标。该游标能够随后使用dblink_fetch()和dblink_close()进行操纵。
参数
connname
要使用的连接名。忽略这个参数将使用未命名连接。
cursorname
要赋予给这个游标的名称。
你希望在远程数据库中执行的SELECT语句,例如select * from pg_class。
fail_on_error
如果为真(忽略时的默认值),那么在连接的远端抛出的一个错误也会导致本地抛出一个错误。如果为假,远程错误只在本地被报告为一个 NOTICE,并且该函数的返回值被设置为ERROR。
返回值
返回状态,OK或者ERROR。
注解
因为一个游标只能在一个事务中持续,如果远端还没有在一个事务中,dblink_open会在远端开始一个显式事务块(BEGIN)。当匹配的dblink_close被执行时,这个事务将再次被关闭。注意如果你使用dblink_exec在dblink_open和dblink_close之间改变数据,并且接着发生了一个错误或者你在dblink_close之前使用了dblink_disconnect,你的更改将被丢失,因为事务将被中止。
例子
SELECT dblink_connect('dbname=postgres options=-csearch_path=');
dblink_connect
----------------
OK
(1 row)
SELECT dblink_open('foo', 'select proname, prosrc from pg_proc');
dblink_open
-------------
OK
(1 row)
**dblink_fetch**
dblink_fetch --- 从一个远程数据库中的打开的游标返回行
大纲
dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 record 集合
dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error])
返回 record 集合
描述
dblink_fetch由之前dblink_open建立的游标中取得行。
参数
connname
要使用的连接名。忽略这个参数将使用未命名连接。
cursorname
要从中取数据的游标名。
howmany
要检索的最大行数。从当前游标位置向前的接下来howmany个行会被取出。一旦该游标已经到达了它的末端,将不会产生更多行。
fail_on_error
如果为真(忽略时的默认值),那么在连接的远端抛出的一个错误也会导致本地抛出一个错误。如果为假,远程错误只在本地被报告为一个 NOTICE,并且该函数不反回行。
返回值
该函数返回从游标中取出的行。要使用这个函数,你将需要指定想要的列集合,如前面dblink中所讨论的。
注解
当FROM子句中指定的返回列的数量和远程游标返回的实际列数不匹配时,将抛出一个错误。
在这个事件中,远程游标仍会前进错误,没发生时前进的行数。对于远程FETCH完成之后,在本地查询中发生的任何错误,情况也是一样。
例子
SELECT dblink_connect('dbname=postgres options=-csearch_path=');
dblink_connect
----------------
OK
(1 row)
SELECT dblink_open('foo', 'select proname, prosrc from pg_proc where proname
like ''bytea%''');
dblink_open
-------------
OK
(1 row)
SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
funcname | source
----------+----------
byteacat | byteacat
byteacmp | byteacmp
byteaeq | byteaeq
byteage | byteage
byteagt | byteagt
(5 rows)
SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
funcname | source
-----------+-----------
byteain | byteain
byteale | byteale
bytealike | bytealike
bytealt | bytealt
byteane | byteane
(5 rows)
SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
funcname | source
------------+------------
byteanlike | byteanlike
byteaout | byteaout
(2 rows)
SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
funcname | source
----------+--------
(0 rows)
**dblink_close**
dblink_close --- 关闭一个远程数据库中的游标
大纲
dblink_close(text cursorname [, bool fail_on_error]) 返回 text
dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text
描述
dblink_close关闭一个之前由dblink_open打开的游标。
参数
connname
要使用的连接名。忽略这个参数将使用未命名连接。
cursorname
要关闭的游标名。
fail_on_error
如果为真(忽略时的默认值),那么在连接的远端抛出的一个错误也会导致本地抛出一个错误。如果为假,远程错误只在本地被报告为一个 NOTICE,并且该函数的返回值被设置为ERROR。
返回值
返回状态,OK或者ERROR。
注解
如果dblink_open开始了一个显式事务块,并且这是连接中最后一个保持打开的游标,dblink_close将发出匹配的COMMIT。
例子
SELECT dblink_connect('dbname=postgres options=-csearch_path=');
dblink_connect
----------------
OK
(1 row)
SELECT dblink_open('foo', 'select proname, prosrc from pg_proc');
dblink_open
-------------
OK
(1 row)
SELECT dblink_close('foo');
dblink_close
--------------
OK
(1 row)
**dblink_get_connections**
dblink_get_connections --- 返回所有打开的命名 dblink 连接的名称
大纲
dblink_get_connections() 返回 text[]
描述
dblink_get_connections返回一个数组,所有打开的命名dblink连接的名称。
返回值
返回一个连接名称的文本数组,如果没有则为 NULL。
例子
SELECT dblink_get_connections();
**dblink_error_message**
dblink_error_message --- 得到在命名连接上的最后一个错误消息
大纲
dblink_error_message(text connname) 返回 text
描述
dblink_error_message为给定连接取得最近的远程错误消息。
参数
connname
要使用的连接名。
返回值
返回最后一个错误消息,如果在这个连接上没有错误则返回一个OK。
注释
当异步查询由dblink_send_query启动时,与连接相关的错误消息可能不会得到更新,直到服务器的响应消息被用掉。 这通常意味着dblink_is_busy或dblink_get_result应在dblink_error_message之前被调用,以使得异步查询产生的任何错误都是可见的。
例子
SELECT dblink_error_message('dtest1');
dblink_send_query
dblink_send_query --- 发送一个异步查询到远程数据库
大纲
dblink_send_query(text connname, text sql) 返回 int
描述
dblink_send_query发送一个要被异步执行的查询,不需要立即等待结果。在该连接上不能有还在处理中的异步查询。
在成功地派送一个异步查询后,可以用dblink_is_busy检查完成状态,并且结果最终由dblink_get_result收集。也可以使用dblink_cancel_query尝试取消一个活动中的异步查询。
参数
connname
要使用的连接名。
sql
你希望在远程数据库中执行的 SQL 语句,例如select * from pg_class。
返回值如果查询被成功地派送返回 1,否则返回 0。
例子
SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3');
**dblink_is_busy**
dblink_is_busy --- 检查连接是否正在异步查询
大纲
dblink_is_busy(text connname) 返回 int
描述
dblink_is_busy测试是否异步查询正在进行中
参数
connname
要检查的连接名。
返回值
如果连接正忙,则返回 1,如果不忙则返回 0。如果这个函数返回 0,dblink_get_result将被保证不会阻塞。
例子
SELECT dblink_is_busy('dtest1');
**dblink_get_notify**
dblink_get_notify --- 在一个连接上检索异步通知
大纲
dblink_get_notify() 返回 (notify_name text, be_pid int, extra text) 集合
dblink_get_notify(text connname) 返回 (notify_name text, be_pid int, extra text)集合
描述
dblink_get_notify在一个未命名连接或者一个指定的命名连接上检索通知。要通过 dblink接收通知,首先必须使用dblink_exec发出LISTEN。
参数
connname
要得到通知的命名连接的名称。
返回值
返回 (notify_name text, be_pid int, extra text) 集合,或者一个空集。
例子
SELECT dblink_exec('LISTEN virtual');
dblink_exec
-------------
LISTEN
(1 row)
SELECT * FROM dblink_get_notify();
notify_name | be_pid | extra
-------------+--------+-------
(0 rows)
NOTIFY virtual;
NOTIFY
SELECT * FROM dblink_get_notify();
notify_name | be_pid | extra
-------------+--------+-------
virtual | 1229 |
(1 row)
**dblink_get_result**
dblink_get_result --- 得到一个异步查询结果
大纲
dblink_get_result(text connname [, bool fail_on_error]) 返回 record 集合
描述
dblink_get_result收集之前dblink_send_query发送的一个异步查询的结果。如果该查询还没有完成,dblink_get_result将等待直到它完成。
参数
connname
要使用的连接名。
fail_on_error
如果为真(忽略时的默认值),那么在连接的远端抛出的一个错误也会导致本地抛出一个错误。如果为假,远程错误只在本地被报告为一个 NOTICE,并且该函数不返回行。
返回值
对于一个异步查询(也就是一个返回行的 SQL 语句),该函数返回查询产生的行。要使用这个函数,你将需要指定所期待的列集合,如前面为dblink所讨论的那样。
对于一个异步命令(也就是一个不返回行的 SQL 语句),该函数返回一个只有单个文本列的单行,其中包含了该命令的状态字符串。必须在调用的FROM子句中指定结果,将具有一个单一文本行。
注解
如果dblink_send_query返回 1,这个函数就必须被调用。对每一个已发送的查询都必须调用一次这个函数,并且再次连接可用之前,还要多调用一次来得到一个空结果集。
当使用dblink_send_query和dblink_get_result时,将结果集中的任何一行,返回给本地查询处理器之前,dblink将取得整个远程查询结果。如果该查询返回大量的行,这可能会导致本地会话中短暂的内存膨胀。最好将这样的一个查询用dblink_open打开,成一个游标并且接着每次取得数量可管理的行。也可以使用简单的dblink(),它会避免缓冲大型结果集到磁盘上导致的内存膨胀。
例子
contrib_regression=# SELECT dblink_connect('dtest1',
'dbname=contrib_regression');
dblink_connect
----------------
OK
(1 row)
contrib_regression=# SELECT * FROM
contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 < 3') AS t1;
t1
----
1
(1 row)
contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+------------
0 | a | {a0,b0,c0}
1 | b | {a1,b1,c1}
2 | c | {a2,b2,c2}
(3 rows)
contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+----
(0 rows)
contrib_regression=# SELECT * FROM
contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 < 3;
contrib_regression-# select * from foo where f1 > 6') AS t1;
t1
----
1
(1 row)
contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+------------
0 | a | {a0,b0,c0}
1 | b | {a1,b1,c1}
2 | c | {a2,b2,c2}
(3 rows)
contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+---------------
7 | h | {a7,b7,c7}
8 | i | {a8,b8,c8}
9 | j | {a9,b9,c9}
10 | k | {a10,b10,c10}
(4 rows)
contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+----
(0 rows)
**dblink_cancel_query**
dblink_cancel_query --- 在命名连接上取消任何活动查询
大纲
dblink_cancel_query(text connname) 返回 text
描述
dblink_cancel_query尝试命名连接上正在进行的任何查询。注意这不一定会成功(例如,远程查询可能已经结束)。一个取消请求仅仅提高了该查询将很快失败的几率。你仍必须完成通常的查询协议,例如通过调用dblink_get_result。
参数
connname
要使用的连接名。
返回值
如果取消请求已经被发送,则返回OK;如果失败,则返回一个错误消息的文本。
例子
SELECT dblink_cancel_query('dtest1');
dblink_get_pkey
dblink_get_pkey --- 返回一个关系的主键域位置和域名称
大纲
dblink_get_pkey(text relname) 返回 dblink_pkey_results 集合
描述
dblink_get_pkey提供有关于本地数据库中一个关系的主键的信息。这有助于生成要被发送到远程数据库的查询。
参数
relname
一个本地关系的名称,例如foo或者myschema.mytab。如果该名称是大小写混合的或包含特殊字符,要包括双引号,例如"FooBar";如果没有引号,字符串将被折叠到小写形式。
返回值
为每一个主键域返回一行,如果该关系没有主键,则不返回行。结果行类型被定义为:
CREATE TYPE dblink_pkey_results AS (position int, colname text);
position列值可以从 1 到 N,它是该域在主键中的编号,而不是在表列中的编号。
例子
CREATE TABLE foobar (
f1 int,
f2 int,
f3 int,
PRIMARY KEY (f1, f2, f3)
);
CREATE TABLE
SELECT * FROM dblink_get_pkey('foobar');
position | colname
----------+---------
1 | f1
2 | f2
3 | f3
(3 rows)
**dblink_build_sql_insert**
dblink_build_sql_insert --- 使用一个本地元组构建一个 INSERT 语句,将主键域值替换为提供的值
大纲
dblink_build_sql_insert(text relname,
int2vector primary_key_attnums,
integer num_primary_key_atts,
text[] src_pk_att_vals_array,
text[] tgt_pk_att_vals_array) 返回 text
描述
dblink_build_sql_insert在选择性地将一个本地表复制到一个远程数据库时很有用。它基于主键从本地表选择一行,接着构建一个复制该行的INSERT命令,但是其中主键值被替换为最后一个参数中的值(要创建该行的一个准确拷贝,只要为最后两个参数指定相同的值)。
参数
relname 一个本地关系的名称,例如foo或者myschema.mytab。如果该名称是大小写混合的或包含特殊字符,要包括双引号,例如"FooBar";如果没有引号,字符串将被折叠到小写形式。
primary_key_attnums 主键域的属性号(从1 开始),例如1 2。 num_primary_key_atts 主键域的数量。src_pk_att_vals_array 要被用来查找本地元组的主键域值。每一个域都被表示为文本形式。如果没有行具有这些主键值,则抛出一个错误。
tgt_pk_att_vals_array 要被替换到结果INSERT命令中的主键域值。每一个域被表示为文本形式。
返回值
将要求的 SQL 语句返回为文本。
注解
primary_key_attnums中的属性号被解释为逻辑列号,对应于列在SELECT * FROM relname中的位置。如果指示出列的左边有任意列在该表的生存期内被删除。
例子
SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_insert
-------------------------------------------------- INSERT INTO foo(f1,f2,f3) VALUES('1','b''a','1') (1 row)
**dblink_build_sql_delete**
dblink_build_sql_delete --- 使用所提供的主键域值构建一个DELETE 语句
大纲
dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] tgt_pk_att_vals_array) 返回 text
描述
dblink_build_sql_delete在选择性地将一个本地表复制到一个远程数据库时很有用。它构建一个 SQL DELETE命令用来删除具有给定主键值的行。
参数
relname
一个本地关系的名称,例如foo或者myschema.mytab。如果该名称是大小写混合的或包含特殊字符,要包括双引号,例如"FooBar";如果没有引号,字符串将被折叠到小写形式。
primary_key_attnums 主键域的属性号(从 1 开始),例如1 2。 num_primary_key_atts 主键域的数量。tgt_pk_att_vals_array 要用在结果DELETE命令中的主键域值。每一个域都被表示为文本形式。返回值将要求为文本 。
注解
primary_key_attnums中的属性号被解释为逻辑列号,对应于列在SELECT * FROM relname中的位置。如果指示出的列的左边有任意列,在该表的生存期内被删除。
例子
SELECT dblink_build_sql_delete('"MyFoo"', '1 2', 2, '{"1", "b"}'); dblink_build_sql_delete
---------------------------------------------
DELETE FROM "MyFoo" WHERE f1='1' AND f2='b'
(1 row)
**dblink_build_sql_update**
dblink_build_sql_update --- 使用一个本地元组构建一个UPDATE 语句,将主键域值替换为提供的值
大纲
dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, text[] tgt_pk_att_vals_array) 返回 text
描述
dblink_build_sql_update在选择性地将一个本地表复制到一个远程数据库时很有用。它从本地表基于主键选择一行,并且接着构建一个UPDATE命令来复制该行,但是其中的主键值被替换为最后一个参数中的值(要创建该行的一个准确拷贝,只要为最后两个参数指定相同的值)。UPDATE命令总是为该行的所有域赋值 --- 这个函数与dblink_build_sql_insert之间的主要区别是它假定目标行已经存在于远程表中。
参数
relname
一个本地关系的名称,例如foo或者myschema.mytab。如果该名称是大小写混合的或包含特殊字符,要包括双引号,例如"FooBar";如果没有引号,字符串将被折叠到小写形式。
primary_key_attnums
主键域的属性号(从 1 开始),例如1 2。
num_primary_key_atts
主键域的数量。
src_pk_att_vals_array
要被用来查找本地元组的主键域值。每一个域都被表示为文本形式。如果没有行具有这些主键值,则抛出一个错误。
tgt_pk_att_vals_array 要用在结果UPDATE命令中的主键域值。每一个域都被表示为文本形式。 返回值将要求的 SQL 语句返回为文本。
注解
primary_key_attnums中的属性号被解释为逻辑列号,对应于列在SELECT * FROM relname中的位置。如果指示出的列的左边有任意列在该表的生存期内被删除。
例子
SELECT dblink_build_sql_update('foo', '1 2', 2, '{"1", "a"}', '{"1", "b"}');
dblink_build_sql_update
-------------------------------------------------------------
UPDATE foo SET f1='1',f2='b',f3='1' WHERE f1='1' AND f2='b'
(1 row)
dict_int
dict_int是一个附加全文搜索词典模板的例子。这个例子词典的动机是控制整数(有符号和无符号)的索引,允许在阻止唯一词数量的过度增长(会严重影响搜索性能)时也能索引这些数字。
这个模块被视为"trusted",也就是说,它可以在当前数据库上具有CREATE特权的非超级用户安装。
D.11.1. 配置
该词典接受三个选项:
• maxlen参数指定在一个整数词中允许的最大位数。默认值为 6。
• rejectlong参数指定一个超长整数是否应该被截断或忽略。如果rejectlong为false(默认),该词典返回该整数的第一个数字。如果rejectlong为true,该词典将一个超长整数作为一个停用词对待,因此它将不会被索引。注意:这也意味着这样一个整数不能被搜索。
• absval 参数规定"+" 或 "-"符号是否将从整数前删除。缺省为 false. 当为 true时,在maxlen被应用之前,符号被删除。
用法
安装dict_int扩展会使用默认参数创建一个文本搜索模板intdict_template和一个基于它的词典intdict。你可以修改参数,例如
test=# ALTER TEXT SEARCH DICTIONARY intdict (MAXLEN = 4, REJECTLONG = true);
ALTER TEXT SEARCH DICTIONARY
或者创建基于该模板的新词典。
要测试该词典,可以尝试
test=# select ts_lexize('intdict', '12345678');
ts_lexize
-----------
{}
(1 row)
dict_xsyn
dict_xsyn(扩展同义词字典)是一个附加全文搜索字典模板的例子。这种字典类型将词替换为它们的同义词分组,并且让任意一同义词进行搜索变得可能。
配置
一个dict_xsyn词典接受以下选项:
• matchorig控制该词典是否接受原生词。默认为true。
• matchsynonyms控制该词典是否接受同义词。默认为false。
• keeporig控制原生词是否被包括在词典的输出中。默认为true。
• keepsynonyms控制同义词是否被包括在词典的输出中。默认为true。
• rules是包含同义词列表的文件的基本名。这个文件必须被存储在$SHAREDIR/ tsearch_data/(其中$SHAREDIR表示Halo安装的共享数据目录)中。它的名称必须以.rules结束(这不包括在rules参数中)。
规则文件具有下面的格式:
• 每一行表示一个单一词的同义词分组,它在该行中首先被给出。同义词被空白分隔,这样:word syn1 syn2 syn3
• 井号(#)是注释定界符。它可以出现在一行中的任何位置。该行的剩余部分将被跳过。例如,可以看看安装在$SHAREDIR/tsearch_data/中的xsyn_sample.rules。
用法
安装dict_xsyn扩展会用默认参数创建一个文本搜索模板xsyn_template以及一个基于它的词典xsyn。你可以修改参数,例如
ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=false);
ALTER TEXT SEARCH DICTIONARY 或者基于该模板创建新的词典。
要测试该词典,你可以尝试
test=# SELECT ts_lexize('xsyn', 'word');
ts_lexize
-----------
(1 row)
ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=true);
ALTER TEXT SEARCH DICTIONARY
SELECT ts_lexize('xsyn', 'word');
ts_lexize
-----------------------
{word,syn1,syn2,syn3}
ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=false, MATCHSYNONYMS=true);
ALTER TEXT SEARCH DICTIONARY
SELECT ts_lexize('xsyn', 'syn1');
ts_lexize
-----------------------
{syn1,syn2,syn3}
ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=true, MATCHORIG=false, KEEPSYNONYMS=false);
ALTER TEXT SEARCH DICTIONARY
SELECT ts_lexize('xsyn', 'syn1');
ts_lexize
-----------------------
{word}
看起来像这样:ALTER TEXT SEARCH CONFIGURATION english
ALTER MAPPING FOR word, asciiword WITH xsyn, english_stem;
earthdistance
earthdistance模块提供两种不同的方法来计算地球表面的大圆距离。 第一种要介绍的依赖于cube模块。第二种基于内建的point数据类型,为座标使用精度和纬度。
在这个模块中,地球被假定为完美的球型。
cube模块必须在earthdistance之前被安装。(尽管你可以使用CREATE EXTENSION的CASCADE选项在一个命令中同时安装)。
小心:强烈建议将 earthdistance和cube安装在同一模式中,并且该模式的 CREATE 特权尚未授予且不会授予任何不受信任的用户。否则,如果earthdistance的模式包含由敌对用户定义的对象,则存在安装时的安全隐患。 此外,在安装后使用earthdistance的函数时,整个搜索路径应仅包含受信任的架构。
基于立方体的地球距离
数据被存储在立方体中,立方体的点(所有的角都一样)使用3个座标表示到地球中心的 x、y 和 z 距离。提供了一个cube之上的域earth,这包括检查值符合这些限制并且合理地接近于地球的真实表面的约束。
地球的半径获得自earth()函数。其单位是米。但是通过改变这一个函数你能够把该模块改为使用某些其他单位,或者使用一种你认为更合适的不同半径值。这个包也有在天文数据库中的应用。天文学家可能想要改变earth()来返回一个180/pi()的半径,这样距离就会是度数。
函数也被提供来支持经纬度输入(以度数)、经纬度输出、计算两点间的大圆距离以及容易地指定一个可用于索引搜索的边界框。 所提供的函数在表 D.5中描述。
表 D.5. 基于立方体的地球距离函数
函数/描述
earth () → float8 返回假定的地球半径。
sec_to_gc ( float8 ) → float8 将地球表面两点间的普通直线(切线)距离转换为它们之间的大圆距离。
gc_to_sec ( float8 ) → float8 将地球表面两点间的大圆距离转换为它们之间的普通直线(切线)距离。
ll_to_earth ( float8, float8 ) → earth 返回以度数给定的纬度(参数 1)和经度(参数 2)的点在地球表面上的位置。
latitude ( earth ) → float8 返回地球表面上一个点的纬度(以度数形式)。
longitude ( earth ) → float8 返回地球表面上的点的经度(以度数形式)。
earth_distance ( earth, earth ) → float8 返回地球表面上两个点之间的大圆距离。
earth_box ( earth, float8 ) → cube 为一个位置的给定大圆距离范围内的点使用cube@>操作符返回一个适合于索引搜索的框。这个框中的某些点到该位置的大圆距离会超过指定的大圆距离,因此使用earth_distance的第二次检查应该被包括在查询中。
基于点的地球距离
这个模块的第二部分依赖于将地球位置表示为类型point的值,其中第一部分被用来表示经度数,第二部分被用来表示纬度数。点被取做 (longitude, latitude) 并且不能反过来,因为经度更接近直观上的 x 轴,而纬度则接近 y 轴。 如表 D.6所示,这一部分只提供了一个单一操作符。
表 D.6. 基于点的地球距离操作符
操作符/描述
point point → float8 计算地球表面上两个点之间以法定英里计算的距离。
注意和这个模块的基于cube的部分不同,这里的单位是被硬编码的:改变earth()函数将不会影响这个操作符的结果。
经度/纬度表示的一个缺点是你需要小心靠近两极和靠近经度正负 180 度处的边界情况。基于cube的表示可以避免这些不连续性。