hstore

hstore

hstore模块实现了一种数据类型,用于在单个Greenplum数据库数据字段中存储(键,值)对的集合。 这在各种情况下很有用,例如具有许多很少检查的属性的行或半结构化数据。

在当前的实现中,键和值字符串的长度都不能超过65535个字节。 如果超出此限制,将引发错误。 这些最大长度可能会在将来的版本中更改。

安装hstore

在使用hstore数据类型和函数之前, 请在要查询其他数据库的每个数据库中运行安装脚本$GPHOME/share/postgresql/contrib/hstore.sql
$ psql -d testdb -f $GPHOME/share/postgresql/contrib/hstore.sql

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视为普通数据值,请使用双引号引起来。

当前,即使不是绝对必要,双引号始终用于在输出中包含键和值字符串。

hstore运算符和函数

Table 1. 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
Note: 不推荐使用=>运算符,并且可能在以后的版本中将其删除。 请改用hstore(text, text)函数。
Table 2. 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是否包含非空值? defined('a=>NULL','a') f
delete(hstore,text) hstore 删除匹配键的所有项 delete('a=>1,b=>2','b') "a"=>"1"

Indexes

hstore@>?运算符有索引支持。 您可以使用GiST或GIN索引类型。例如:

CREATE INDEX hidx ON testhstore USING GIST(h);

CREATE INDEX hidx ON testhstore USING GIN(h);
   

示例

添加键,或使用新键更新现有键:

UPDATE tab SET h = h || ('c' => '3');

删除键:

UPDATE tab SET h = delete(h, 'k1');

统计

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
...................