hstore是一种数据类型,用途是存储在一个PostgreSQL值中存储键值对(文本字符串)。当前数据库中具有CREATE权限的普通用户即可创建该模块。
hstore安装
使用root用户,切换到已安装数据库的postgresql安装包的解压目录contrib/hstore下,执行:
make
make install
然后进入数据库,执行:
postgres=# create extension hstore ;
CREATE EXTENSION
hstore使用
hstore值由0个或多个“键=>值”对(以逗号分隔)组成。如:
k => v
foo =>bar, baz=>whatever
“l-a” => “anything at all”
键值对非强顺序。hstore中的键是唯一的,若向hstore中同时输入两个相同的键,则会随机保留一个(不保证确切哪一个):
postgres=# select ‘a=>1,a=>2’::hstore;
hstore
-————-
“a”=>”1”
(1 row)
hstore的操作符及函数
hstore的操作符
操作符
介绍
示例
hstore->text返回text类型
返回指定键的值
postgres=# select ‘a=>1,b=>2’::hstore->’a’;
?column?
-————-
1
(1 row)
hstore->test[]返回text[]类型
返回指定键的值
postgres=# select ‘a=>1,b=>2,c=>3’::hstore->array[‘a’,’b’];
?column?
-————-
{1,2}
(1 row)hstore||hstore返回hstore
连接两个hstore
postgres=# select ‘a=>1’::hstore||’b=>2’::hstore;
?column?
-—————————-
“a”=>”1”, “b”=>”2”
(1 row)
hstore?text返回Boolean类型
hstore是否包含指定的键
postgres=# select ‘a=>1’::hstore ? ‘b’;
?column?
-————-
f
(1 row)hstore ?& text[]返回Boolean类型
hstore是否包含指定的所有键
postgres=# select ‘a=>1’::hstore ?& array[‘a’,’b’];
?column?
-————-
f
(1 row)
hstore ?| text[] 返回Boolean类型
hstore是否包含指定的所有键的任意一个
postgres=# select ‘a=>1’::hstore ?| array[‘a’,’b’];
?column?
-————-
t
(1 row)
hstore @> hstore返回Boolean类型
左边的操作数是否包含右边的操作数
postgres=# select ‘a=>1’::hstore @> ‘b=>1,a=>1’;
?column?
-————-
f
(1 row)
hstore<@hstore返回Boolean类型
右边的操作数是否包含左边的操作数
postgres=# select ‘a=>1’::hstore <@ ‘b=>1,a=>1’;
?column?
-————-
t
(1 row)hstore - text返回hstore类型
从左操作数据删除键
postgres=# select ‘a=>1,b=>1’::hstore - ‘a’::text;
?column?
-————-
“b”=>”1”
(1 row)
hstore - text[]返回hstore类型
从左操作数据删除多个键
postgres=# select ‘a=>1,b=>1,c=>1’::hstore - array[‘a’,’b’];
?column?
-————-
“c”=>”1”
(1 row)
hstore - hstore返回hstore类型
从左操作数中删除在右操作数中匹配的键值对
postgres=# select ‘a=>1,b=>1,c=>1’::hstore - ‘a=>2,b=>1’::hstore;
?column?
-—————————-
“a”=>”1”, “c”=>”1”
(1 row)anyelement #= hstore返回anyelement
将左操作数(必须为复合类型)的区域替换为hstore中的匹配值
postgres=# select row(1,2,3) #= ‘f2=>22’::hstore;
?column?
-————-
(1,22,3)
(1 row)
%%hstore返回text[]类型
将hstore转为键值数组。
postgres=# select %% ‘a=>1,b=>2’::hstore;
?column?
-—————
{a,1,b,2}
(1 row)
%#hstore返回text[]类型
将hstore转为二维键值数组
postgres=# select %# ‘a=>1,b=>2’::hstore;
?column?
-———————
{{a,1},{b,2}}
(1 row)
hstore的函数
函数
介绍
示例
hstore(record)返回hstore类型
为记录或行构建hstore类型
postgres=# select hstore(row(1,2));
hstore
-——————————-
“f1”=>”1”, “f2”=>”2”
(1 row)
hstore(text[])返回hstore类型
为键值数组或二维数组构建hstore类型
postgres=# select hstore(array[‘a’,’1’,’b’,’2’]);
hstore
-—————————-
“a”=>”1”, “b”=>”2”
(1 row)
postgres=# select hstore(array[[‘a’,’1’],[‘b’,’2’]]);
hstore
-—————————-
“a”=>”1”, “b”=>”2”
(1 row)
hstore(text[],text[])返回hstore类型
为分离的键值数组构建hstore类型
postgres=# select hstore(array[‘a’,’b’],array[‘1’,’2’]);
hstore
-—————————-
“a”=>”1”, “b”=>”2”
(1 row)
hstore(text,text)返回hstore类型
构建单项hstore类型
postgres=# select hstore(‘1’,’2’);
hstore
-————-
“1”=>”2”
(1 row)akeys(hstore)返回文本类型
提取hstore的键,将其作为数组返回
postgres=# select akeys(‘a=>1,b=>2’);
akeys
-———
{a,b}
(1 row)
skeys(hstore)返回文本类型
提取hstore的键,将其作为数集返回
postgres=# select skeys(‘a=>1,b=>2’);
skeys
-———
a
b
(2 rows)avals(hstore)返回文本类型
提取hstore的值,将其作为数组返回
postgres=# select avals(‘a=>1,b=>2’);
avals
-———
{1,2}
(1 row)
svals(hstore)返回文本类型
提取hstore的值,将其作为数集返回
postgres=# select svals(‘a=>1,b=>2’);
svals
-———
1
2
(2 rows)hstore_to_array(hstore)返回文本类型
提取hstore的键值,作为数组返回
postgres=# select hstore_to_array(‘a=>1,b=>2’);
hstore_to_array
-————————
{a,1,b,2}
(1 row)hstore_to_matrix(hstore)返回文本类型
提取hstore的键值,作为二维数组返回
postgres=# select hstore_to_matrix(‘a=>1,b=>2’);
hstore_to_matrix
-————————-
{{a,1},{b,2}}
(1 row)hstore_to_json(hstore)返回json类型
将hstore转为json值。在将hstore值转为json时隐式使用该函数。
postgres=# select hstore_to_json(‘a=>1,b=>2’);
hstore_to_json
-——————————-
{“a”: “1”, “b”: “2”}
(1 row)
hstore_to_jsonb(hstore)返回jsonb类型
将hstore转为jsonb值。在将hstore值转为jsonb时隐式使用该函数。
postgres=# select hstore_to_jsonb(‘a=>1,b=>2’);
hstore_to_jsonb
-——————————-
{“a”: “1”, “b”: “2”}
(1 row)hstore_to_json_loose(hstore)返回json类型
将hstore转为json值,不过在JSON中不给数字和布尔值加双引号
postgres=# select hstore_to_json_loose(‘a=>1,b=>2’);
hstore_to_json_loose
-——————————-
{“a”: 1, “b”: 2}
(1 row)
hstore_to_jsonb_loose(hstore)返回jsonb类型
将hstore转为jsonb值,不过在JSON中不给数字和布尔值加双引号
postgres=# select hstore_to_jsonb_loose(‘a=>1,b=>2’);
hstore_to_jsonb_loose
--——————————-
{“a”: 1, “b”: 2}
(1 row)slice(hstore,text[])返回hstore类型
提取hstore中的指定键值
postgres=# select slice(‘a=>1,b=>2’,array[‘a’]);
slice
-————-
“a”=>”1”
(1 row)each(hstore)返回set of record(key text,value text)
提取hstore中的指定键值,以记录集方式返回
postgres=# select each(‘a=>1,b=>2’);
each
-———
(a,1)
(b,2)
(2 rows)
postgres=# select * from each(‘a=>1,b=>2’);
key | value
——-+———-
a | 1
b | 2
(2 rows)exist(hstore,text)返回布尔值
判断hstore是否包含某个键
postgres=# select exist(‘a=>1,b=>2’,’a’);
exist
-———
t
(1 row)defined(hstore,text)返回布尔值判断hstore是否为键定义非空值
postgres=# select defined(‘a=>1,b=>2’,’a’);
defined
-————
t
(1 row)
delete(hstore,text)返回hstore类型值
删除匹配的键值
postgres=# select delete(‘a=>1,b=>2’,’a’);
delete
-————-
“b”=>”2”
(1 row)
delete(hstore,text[])返回hstore类型值
删除匹配的键值
postgres=# select delete(‘a=>1,b=>2,c=>3’,array[‘a’,’b’]);
delete
-————-
“c”=>”3”
(1 row)
delete(hstore,hstore)返回hstore类型值
删除第一个参数在第二个参数中存在的键值
postgres=# select delete(‘a=>1,b=>2,c=>3’,’a=>2,b=>2,c=>3’::hstore);
delete
-————-
“a”=>”1”
(1 row)populate_record(anyelement,hstore)返回anyelement
用匹配的右边值替换左边值(左边操作数必须为复合类型)
postgres=# select populate_record(row(1,2,3),’f2=>22’::hstore);
populate_record
-————————
(1,22,3)
(1 row)
索引
hstore对@>,?,?&以及?|操作符提供GiST和GIN索引支持。例如:
CREATE INDEX hidx ON testhstore USING GIST(h);
CREATE INDEX hidx ON testhstore USING GIN(h);
GIST操作类gist_hstore_ops可将键值对作为位图签名。其可选整型参数siglen可指定签名长度(单位为byte)。默认长度是16位。签名长度可介于1-2024字节。更长的签名会导致更精细的搜索(检索更小的索引的块以及更少的页),不过会导致更大的索引。
以签名长度为32字节的创建索引示例:
CREATE INDEX hidx ON testhstore USING GIST(h gist_hstore_ops(siglen=32));
hstore对等号支持btree及hash索引,此特性使得hstore列可声明为unique或在GROUP BY、ORDER BY或DISTINCT中使用。创建此类索引:
CREATE INDEX hidx ON testhstore USING BTREE (h);
CREATE INDEX hidx ON testhstore USING HASH(h);
示例
添加键或更新键值:
UPDATE tab SET h=h || hstore(‘c’,’3’);
删除键:
UPDATE tab SET h=delete(h,’kl’);
将记录转为hstore类型:
postgres=# CREATE TABLE test(col1 integer,col2 text,col3 text);
CREATE TABLE
postgres=# INSERT INTO test VALUES(123,’foo’,’bar’);
INSERT 0 1
postgres=# SELECT hstore(t) FROM test AS t;
hstore
-——————————————————————
“col1”=>”123”, “col2”=>”foo”, “col3”=>”bar”
(1 row)
数据统计
postgres=# select * from each(‘aaa=>bq,b=>NULL,””=>1’);
key | value
——-+———-
| 1
b |
aaa | bq
(3 rows)
统计数据:
SELECT key, count(*) FROM
(SELECT (each(h)).key FROM testhstore) AS stat
GROUP BY key
ORDER BY count DESC, key;
兼容性
hstore的PostgreSQL9.0与之前的实现方式不同,不过使用dump/restore进行升级是没问题的。
若使用二进制升级,向上兼容由新的代码可识别旧格式的数据来实现,故而可能会对性能有一些影响。可通过使用以下方式手动对表列数据升级:
UPDATE tablename SET hstorecol=hstorecol || ‘’;
ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol||’’;
transform
可使用额外的扩展实现hstore类型到PL/Perl和PL/Python的转换。针对PL/Perl的扩展为hstore_plperl以及hstore_plperlu。针对PL/Python的是hstore_plpythonu,hstore_plpython2u以及hstore_plpython3u。
注:建议将转换扩展安装到hstore相同的模式下。
点击此处阅读原文
↓↓↓
本文分享自微信公众号 - 开源软件联盟PostgreSQL分会(kaiyuanlianmeng)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。