F.13. hstore #
此模块实现了hstore数据类型,用于在单个
PostgreSQL值中存储一组键/值对。这在多种场景中都很有用,例如属性很多但很少查看的行,或者半结构化数据。
在当前实现中,键和值字符串的长度都不能超过 65535 字节;超过此限制会抛出错误。这些最大长度在未来的发行版中可能会改变。
F.13.1. hstore 的外部表示
hstore 值的文本表示包含零个或多个以逗号分隔的
key => value 项。例如:
k => v
foo => bar, baz => whatever
"1-a" => "anything at all"
项的顺序并不重要(而且在输出时可能不会按原样重现)。项之间或
=> 号周围的空白会被忽略。如果键或值包含空白、逗号、= 或 >,请使用双引号。要在键或值中包含双引号或反斜线,请在其前面再加一个反斜线。(记住,根据
standard_conforming_strings 的设置,你可能需要在 SQL 字符串字面量中把反斜线写成双份。)
值(但键不能)可以是 SQL NULL。它表示为
key => NULL
NULL 关键字不区分大小写。同样,如果希望字符串
null 被当作普通数据值处理,请使用双引号。
目前,输出时键和值字符串总是用双引号包围,即使严格来说并非必需。
F.13.2. hstore 操作符和函数
表 F.5. hstore 操作符
| 操作符 | 描述 | 示例 | 结果 |
|---|---|---|---|
hstore -> text | 获取键对应的值(不存在时为 null) | 'a=>x, b=>y'::hstore -> 'a' | x |
text => text | 构造单项 hstore | 'a' => 'b' | "a"=>"b" |
hstore || hstore | 连接 | 'a=>b, c=>d'::hstore || 'c=>x, d=>q'::hstore | "a"=>"b", "c"=>"x", "d"=>"q" |
hstore ? text | hstore 是否包含该键? | 'a=>1'::hstore ? 'a' | t |
hstore @> hstore | 左操作数是否包含右操作数? | 'a=>b, b=>1, c=>NULL'::hstore @> 'b=>1' | t |
hstore <@ hstore | 左操作数是否被右操作数包含? | 'a=>c'::hstore <@ 'a=>b, b=>1, c=>NULL' | f |
(在 PostgreSQL 8.2 之前,包含操作符 @> 和 <@ 分别称为 @ 和 ~。这些名称仍然可用,但已弃用,最终将被删除。请注意,旧名称与核心几何数据类型以前采用的约定正好相反!)
注意
=> 操作符已弃用,未来的发行版中可能会将其删除。请改用 hstore(text, text) 函数。
表 F.6. hstore 函数
| 函数 | 返回类型 | 描述 | 示例 | 结果 |
|---|---|---|---|---|
hstore(text, text) | hstore | 构造单项 hstore | hstore('a', 'b') | "a"=>"b" |
akeys(hstore) | text[] | 将 hstore 的键作为数组获取 | akeys('a=>1,b=>2') | {a,b} |
skeys(hstore) | setof text | 将 hstore 的键作为集合获取 | skeys('a=>1,b=>2') | a b |
avals(hstore) | text[] | 将 hstore 的值作为数组获取 | avals('a=>1,b=>2') | {1,2} |
svals(hstore) | setof text | 将 hstore 的值作为集合获取 | svals('a=>1,b=>2') | 1 2 |
each(hstore) | setof(key text, value text) | 将 hstore 的键和值作为集合获取 | select * from each('a=>1,b=>2') | key | value -----+------- a | 1 b | 2 |
exist(hstore,text) | boolean | hstore 是否包含该键? | exist('a=>1','a') | t |
defined(hstore,text) | boolean | hstore 是否包含该键的非空(non-null)值? | defined('a=>NULL','a') | f |
delete(hstore,text) | hstore | 删除匹配键的键值对 | delete('a=>1,b=>2','b') | "a"=>"1" |
F.13.3. 索引
hstore支持针对@>和?
操作符的索引。可以使用 GiST 或 GIN 索引类型。例如:
CREATE INDEX hidx ON testhstore USING GIST(h); CREATE INDEX hidx ON testhstore USING GIN(h);
F.13.4. 示例
添加一个键,或用新值更新现有键:
UPDATE tab SET h = h || ('c' => '3');
删除一个键:
UPDATE tab SET h = delete(h, 'k1');
F.13.5. 统计信息
由于hstore类型本身比较宽松,它可能包含大量不同的键。检查键是否合法是应用程序的任务。下面的示例展示了检查键并获取统计信息的几种技术。
简单示例:
SELECT * FROM each('aaa=>bq, b=>NULL, ""=>1');
使用表:
SELECT (each(h)).key, (each(h)).value INTO stat FROM testhstore;
在线统计信息:
SELECT key, count(*) FROM
(SELECT (each(h)).key FROM testhstore) AS stat
GROUP BY key
ORDER BY count DESC, key;
key | count
-----------+-------
line | 883
query | 207
pos | 203
node | 202
space | 197
status | 195
public | 194
title | 190
org | 189
...................
F.13.6. 作者
Oleg Bartunov <oleg@sai.msu.su>,俄罗斯莫斯科,莫斯科大学
Teodor Sigaev <teodor@sigaev.ru>,俄罗斯莫斯科,Delta-Soft Ltd.