2006-09-06 02:00:58 +08:00
|
|
|
Hstore - contrib module for storing (key,value) pairs
|
|
|
|
|
|
|
|
[Online version] (http://www.sai.msu.su/~megera/oddmuse/index.cgi?Hstore)
|
|
|
|
|
|
|
|
Motivation
|
|
|
|
|
|
|
|
Many attributes rarely searched, semistructural data, lazy DBA
|
|
|
|
|
|
|
|
Authors
|
|
|
|
|
|
|
|
* Oleg Bartunov <oleg@sai.msu.su>, Moscow, Moscow University, Russia
|
|
|
|
* Teodor Sigaev <teodor@sigaev.ru>, Moscow, Delta-Soft Ltd.,Russia
|
|
|
|
|
2006-09-06 02:39:08 +08:00
|
|
|
LEGAL NOTICES: This module is released under BSD license (as PostgreSQL
|
|
|
|
itself)
|
2006-09-06 02:00:58 +08:00
|
|
|
|
|
|
|
Operations
|
|
|
|
|
|
|
|
* hstore -> text - get value , perl analogy $h{key}
|
|
|
|
|
|
|
|
select 'a=>q, b=>g'->'a';
|
|
|
|
?
|
|
|
|
------
|
|
|
|
q
|
|
|
|
|
|
|
|
* hstore || hstore - concatenation, perl analogy %a=( %b, %c );
|
|
|
|
|
|
|
|
regression=# select 'a=>b'::hstore || 'c=>d'::hstore;
|
|
|
|
?column?
|
|
|
|
--------------------
|
|
|
|
"a"=>"b", "c"=>"d"
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
but, notice
|
|
|
|
|
|
|
|
regression=# select 'a=>b'::hstore || 'a=>d'::hstore;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
"a"=>"d"
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
* text => text - creates hstore type from two text strings
|
|
|
|
|
|
|
|
select 'a'=>'b';
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
"a"=>"b"
|
|
|
|
|
2006-09-11 01:36:52 +08:00
|
|
|
* hstore @> hstore - contains operation, check if left operand contains right.
|
2006-09-06 02:00:58 +08:00
|
|
|
|
2006-09-11 01:36:52 +08:00
|
|
|
regression=# select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>c';
|
2006-09-06 02:00:58 +08:00
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
2006-09-11 01:36:52 +08:00
|
|
|
regression=# select 'a=>b, b=>1, c=>NULL'::hstore @> 'b=>1';
|
2006-09-06 02:00:58 +08:00
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2006-09-11 01:36:52 +08:00
|
|
|
* hstore <@ hstore - contained operation, check if left operand is contained
|
2006-09-06 02:39:08 +08:00
|
|
|
in right
|
2006-09-06 02:00:58 +08:00
|
|
|
|
2006-09-11 01:36:52 +08:00
|
|
|
(Before PostgreSQL 8.2, the containment operators @> and <@ were
|
|
|
|
respectively called @ and ~. These names are still available, but are
|
|
|
|
deprecated and will eventually be retired. Notice that the old names
|
|
|
|
are reversed from the convention formerly followed by the core geometric
|
|
|
|
datatypes!)
|
|
|
|
|
2006-09-06 02:00:58 +08:00
|
|
|
Functions
|
|
|
|
|
|
|
|
* akeys(hstore) - returns all keys from hstore as array
|
|
|
|
|
|
|
|
regression=# select akeys('a=>1,b=>2');
|
|
|
|
akeys
|
|
|
|
-------
|
|
|
|
{a,b}
|
|
|
|
|
|
|
|
* skeys(hstore) - returns all keys from hstore as strings
|
|
|
|
|
|
|
|
regression=# select skeys('a=>1,b=>2');
|
|
|
|
skeys
|
|
|
|
-------
|
|
|
|
a
|
|
|
|
b
|
|
|
|
|
|
|
|
* avals(hstore) - returns all values from hstore as array
|
|
|
|
|
|
|
|
regression=# select avals('a=>1,b=>2');
|
|
|
|
avals
|
|
|
|
-------
|
|
|
|
{1,2}
|
|
|
|
|
|
|
|
* svals(hstore) - returns all values from hstore as strings
|
|
|
|
|
|
|
|
regression=# select svals('a=>1,b=>2');
|
|
|
|
svals
|
|
|
|
-------
|
|
|
|
1
|
|
|
|
2
|
|
|
|
|
2006-09-06 02:39:08 +08:00
|
|
|
* delete (hstore,text) - delete (key,value) from hstore if key matches
|
|
|
|
argument.
|
2006-09-06 02:00:58 +08:00
|
|
|
|
|
|
|
regression=# select delete('a=>1,b=>2','b');
|
|
|
|
delete
|
|
|
|
----------
|
|
|
|
"a"=>"1"
|
|
|
|
|
|
|
|
* each(hstore) return (key, value) pairs
|
|
|
|
|
|
|
|
regression=# select * from each('a=>1,b=>2');
|
|
|
|
key | value
|
|
|
|
-----+-------
|
|
|
|
a | 1
|
|
|
|
b | 2
|
|
|
|
|
2007-03-14 22:21:53 +08:00
|
|
|
* exist (hstore,text)
|
|
|
|
* hstore ? text
|
|
|
|
- returns 'true if key is exists in hstore and false otherwise.
|
2006-09-06 02:00:58 +08:00
|
|
|
|
2007-03-14 22:21:53 +08:00
|
|
|
regression=# select exist('a=>1','a'), 'a=>1' ? 'a';
|
|
|
|
exist | ?column?
|
|
|
|
-------+----------
|
|
|
|
t | t
|
2006-09-06 02:00:58 +08:00
|
|
|
|
2006-10-12 00:42:51 +08:00
|
|
|
* defined (hstore,text) - returns true if key is exists in hstore and
|
2006-09-06 02:39:08 +08:00
|
|
|
its value is not NULL.
|
2006-09-06 02:00:58 +08:00
|
|
|
|
2006-10-12 00:42:51 +08:00
|
|
|
regression=# select defined('a=>NULL','a');
|
|
|
|
defined
|
|
|
|
---------
|
2006-09-06 02:00:58 +08:00
|
|
|
f
|
|
|
|
|
|
|
|
Indices
|
|
|
|
|
2007-03-14 22:21:53 +08:00
|
|
|
Module provides index support for '@>' and '?' operations.
|
2006-09-06 02:00:58 +08:00
|
|
|
|
|
|
|
create index hidx on testhstore using gist(h);
|
2007-03-14 22:21:53 +08:00
|
|
|
create index hidx on testhstore using gin(h);
|
2006-09-06 02:00:58 +08:00
|
|
|
|
|
|
|
Note
|
|
|
|
|
|
|
|
Use parenthesis in select below, because priority of 'is' is higher than that of '->'
|
|
|
|
|
|
|
|
select id from entrants where (info->'education_period') is not null;
|
|
|
|
|
|
|
|
Examples
|
|
|
|
|
|
|
|
* add key
|
|
|
|
|
|
|
|
update tt set h=h||'c=>3';
|
|
|
|
|
|
|
|
* delete key
|
|
|
|
|
|
|
|
update tt set h=delete(h,'k1');
|
|
|
|
|
|
|
|
* Statistics
|
|
|
|
|
2006-09-06 02:39:08 +08:00
|
|
|
hstore type, because of its intrinsic liberality, could contain a lot of
|
|
|
|
different keys. Checking for valid keys is the task of application.
|
|
|
|
Examples below demonstrate several techniques how to check keys statistics.
|
2006-09-06 02:00:58 +08:00
|
|
|
|
|
|
|
o simple example
|
|
|
|
|
|
|
|
select * from each('aaa=>bq, b=>NULL, ""=>1 ');
|
|
|
|
|
|
|
|
o using table
|
|
|
|
|
|
|
|
select (each(h)).key, (each(h)).value into stat from testhstore ;
|
|
|
|
|
|
|
|
o online stat
|
|
|
|
|
|
|
|
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
|
2006-09-06 02:39:08 +08:00
|
|
|
...................
|