Hstore
From PostgreSQL 中文维基, PostgreSQL 中文站, PostgreSQL 中国社区, PostgreSQL Chinese community
[编辑] hstore
这个模块实现了一个数据类型 hstore 用于在一个 PostgreSQL 数据字段里存储一个(key,value)对的集合。这个类型可以在很多场合很有用们,必须有许多属性的行,或者是半结构化的数据。
[编辑] 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 操作符和函数
| 操作符 | 描述 | 例子 | 结果 |
| hstore -> text | 给键获取值(如果没出现则为空) | '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 是否包含 key? | '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 之前,包含操作符 @> 和 <@ 分别叫 @ 和 ~。这些名称仍然可用,但是已经过时了,并且最后会退休。请注意老名称是因为遵循核心的几何数据类型而设置的!)
| 函数 | 返回类型 | 描述 | 例子 | 结果 |
| 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" |
[编辑] 索引
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
...................
[编辑] 作者
Oleg Bartunov <oleg@sai.msu.su>, Moscow, Moscow University, Russia
Teodor Sigaev <teodor@sigaev.ru>, Moscow, Delta-Soft Ltd., Russia
