现在满地都是KV数据库的文字,PostgreSQL 也有类似的结构。不过是通过其强大的扩展方式实现的。
官网文档请参考:http://www.postgresql.org/docs/current/static/hstore.html
本文测试环境在 Mac OS 下,Pg采用源码编译。
编译 hstore 扩展
mac:~ smallfish$ cd Downloads/postgresql-9.0.1/contrib/hstore/ mac:hstore smallfish$ make ... 一堆编译信息 mac:hstore smallfish$ sudo make install
导入到数据库中,注意必须以 postgres 用户,如果需要装入到指定数据库,请指明。这里采用默认数据库。
mac:hstore smallfish$ ls /opt/postgresql/share/contrib/ hstore.sql uninstall_hstore.sql mac:hstore smallfish$ psql -U postgres -f /opt/postgresql/share/contrib/hstore.sql ... 一堆导入命令
进入数据库,建一个测试表
postgres=# CREATE TABLE testhstore (id SERIAL, value hstore); NOTICE: CREATE TABLE will create implicit sequence "testhstore_id_seq" for serial column "testhstore.id" CREATE TABLE
查看下表结构
postgres=# \d List of relations Schema | Name | Type | Owner --------+-------------------+----------+---------- public | testhstore | table | postgres public | testhstore_id_seq | sequence | postgres (2 rows) postgres=# \d testhstore; Table "public.testhstore" Column | Type | Modifiers --------+---------+--------------------------------------------------------- id | integer | not null default nextval('testhstore_id_seq'::regclass) value | hstore |
尝试下简单 hstore类型
postgres=# select 'a=>1, b=>2'::hstore; hstore -------------------- "a"=>"1", "b"=>"2" (1 row) postgres=# select 'a=>1, b=>a'::hstore; hstore -------------------- "a"=>"1", "b"=>"a" (1 row)
写几条测试数据先
postgres=# INSERT INTO testhstore (value) VALUES ('name=>smallfish, age=>29'::hstore); INSERT 0 1 postgres=# SELECT * FROM testhstore; id | value ----+---------------------------------- 1 | "age"=>"29", "name"=>"smallfish" (1 row) postgres=# INSERT INTO testhstore (value) VALUES ('name=>nnfish, age=>20'::hstore); INSERT 0 1 postgres=# INSERT INTO testhstore (value) VALUES ('name=>aaa, age=>30, addr=>China'::hstore); INSERT 0 1
查看下所有数据
postgres=# SELECT * FROM testhstore; id | value ----+--------------------------------------------- 1 | "age"=>"29", "name"=>"smallfish" 2 | "age"=>"20", "name"=>"nnfish" 3 | "age"=>"30", "addr"=>"China", "name"=>"aaa" (3 rows)
查询列里面的指定 key
postgres=# SELECT id, value->'name' AS name FROM testhstore; id | name ----+----------- 1 | smallfish 2 | nnfish 3 | aaa (3 rows) postgres=# SELECT id, value->'name', value->'age' AS age FROM testhstore; id | ?column? | age ----+-----------+----- 1 | smallfish | 29 2 | nnfish | 20 3 | aaa | 30 (3 rows)
修改列某 key 值
postgres=# UPDATE testhstore SET value=value||('addr=>Shanghai') WHERE id = 2; UPDATE 1 postgres=# SELECT * FROM testhstore; id | value ----+--------------------------------------------------- 1 | "age"=>"29", "name"=>"smallfish" 3 | "age"=>"30", "addr"=>"China", "name"=>"aaa" 2 | "age"=>"20", "addr"=>"Shanghai", "name"=>"nnfish" (3 rows)
删除列里某 key
postgres=# UPDATE testhstore SET value=delete(value, 'addr') WHERE id = 3; UPDATE 1 postgres=# SELECT * FROM testhstore; id | value ----+--------------------------------------------------- 1 | "age"=>"29", "name"=>"smallfish" 2 | "age"=>"20", "addr"=>"Shanghai", "name"=>"nnfish" 3 | "age"=>"30", "name"=>"aaa" (3 rows)
按条件查询列里某 key ,注意要数据类型,CAST 强转。默认都是字符串的值。
postgres=# SELECT * FROM testhstore WHERE (value->'age')::INT > 20; id | value ----+---------------------------------- 1 | "age"=>"29", "name"=>"smallfish" 3 | "age"=>"30", "name"=>"aaa" (2 rows) postgres=# SELECT * FROM testhstore WHERE value->'name' = 'smallfish'; id | value ----+---------------------------------- 1 | "age"=>"29", "name"=>"smallfish" (1 row)