Postgres Data
@vongrippen
arrays
hstore
JSON
https://slid.es/vongrippen/postgres-data
arrays
Exactly what they sound like
(arrays of data)
CREATE TABLE permissions (
id serial PRIMARY KEY,
user_id integer,
perm varchar[]
);
CREATE TABLE permissions (
id serial PRIMARY KEY,
user_id integer,
perm varchar[]
);
INSERT INTO permissions (user_id, perm) VALUES (
1,
'{"read","write","admin"}'
);
INSERT INTO permissions (user_id, perm) VALUES (
2,'{"read"}'
);
INSERT INTO permissions (user_id, perm) VALUES (
3,'{"read","write"}'
);
SELECT * FROM permissions;
id | user_id | perm
----+---------+--------------------
1 | 1 | {read,write,admin}
2 | 2 | {read}
3 | 3 | {read,write}
SELECT user_id, perm FROM permissions WHERE 'write' = ANY(perm);
user_id | perm
---------+--------------------
1 | {read,write,admin}
3 | {read,write}
SELECT user_id, unnest(perm) FROM permissions WHERE 'write' = ANY(perm);
user_id | unnest
---------+--------
1 | read
1 | write
1 | admin
3 | read
3 | write
Resources
hstore
A key-value store in a column
CREATE EXTENSION hstore;
CREATE TABLE items (
id serial PRIMARY KEY,
name varchar,
price real,
attributes hstore
);
CREATE EXTENSION hstore;
CREATE TABLE items (
id serial PRIMARY KEY,
name varchar,
price real,
attributes hstore
);
INSERT INTO items (name, price, attributes) VALUES ( 'MacBook Air',
999.99,
'osx_version => "10.8",
ram => "8G"'
);
INSERT INTO items (name, price, attributes) VALUES (
'Google Galaxy Nexus',
99.99,
'android_version => "4.3",
ram => "2G"'
);
INSERT INTO items (name, price) VALUES (
'Kleenex',
4.99
);
SELECT * FROM items;
id | name | price | attributes
----+---------------------+--------+---------------------------------------
1 | MacBook Air | 999.99 | "ram"=>"8G", "osx_version"=>"10.8"
2 | Google Galaxy Nexus | 99.99 | "ram"=>"2G", "android_version"=>"4.3"
3 | Kleenex | 4.99 |
SELECT name, price, attributes->'osx_version' as osx FROM items WHERE attributes->'osx_version' = '10.8';
name | price | osx
-------------+--------+------
MacBook Air | 999.99 | 10.8
SELECT name, price, attributes->'ram' as ram FROM items WHERE attributes ? 'ram';
name | price | ram
---------------------+--------+-----
MacBook Air | 999.99 | 8G
Google Galaxy Nexus | 99.99 | 2G
CREATE INDEX item_ram ON items ((items.attributes->'ram'));
UPDATE items SET attributes = attributes || '"ram"=>"4G"'::hstore WHERE attributes->'ram' = '8G';
UPDATE items SET attributes = delete(attributes, 'osx_version');
SELECT * FROM items WHERE attributes @> '"ram"=>"2G"'::hstore;
id | name | price | attributes
----+---------------------+-------+---------------------------------------
2 | Google Galaxy Nexus | 99.99 | "ram"=>"2G", "android_version"=>"4.3"
Important Notes
hstore only supports string values*
It's only a single level deep, no nesting **
* In 9.4, hstore is supposed switch to binary storage
allowing additional data types:
allowing additional data types:
** hstore is also supposed to be getting multiple level nesting
much like JSON
Resources
JSON
A[nother] key-value store in a column
CREATE TABLE reports (
id serial PRIMARY KEY,
name varchar,
data json
);
CREATE TABLE reports (
id serial PRIMARY KEY,
name varchar,
data json
);
INSERT INTO reports (name, data) VALUES (
'NoMethodError',
'{"backtrace": [
"sidekiq-2.12.0/lib/sidekiq/exception_handler.rb:21",
"sidekiq-2.12.0/lib/sidekiq/exception_handler.rb:12"
],
"action": "create",
"controller": "cases"}'
);
INSERT INTO reports (name, data) VALUES ( 'SystemStackError', '{"backtrace": ["redis-3.0.4/lib/redis/client.rb:306"],
"action": "update", "controller": "clients"}'
);
SELECT id,data FROM reports;
id | data
----+----------------------------------------------------------------
1 | {"backtrace": [ +
| "sidekiq-2.12.0/lib/sidekiq/exception_handler.rb:21",+
| "sidekiq-2.12.0/lib/sidekiq/exception_handler.rb:12" +
| ], +
| "action": "create", +
| "controller": "cases"}
2 | {"backtrace": ["redis-3.0.4/lib/redis/client.rb:306"], +
| "action": "update", "controller": "clients"}
SELECT id,name FROM reports WHERE data->>'controller' = 'clients';
id | name
----+------------------
2 | SystemStackError
SELECT name, data->'controller' AS controller, data->'action' AS action FROM reports;
name | controller | action
------------------+------------+----------
NoMethodError | "cases" | "create"
SystemStackError | "clients" | "update"
Important Notes
JSON is stored as text*
Querying JSON will be slow, use indexing
* In 9.4, the developers are considering moving to binary storage
Resources
Other Cool Stuff
PL/v8: Run JavaScript in your database
PostGIS: Spatial and Geographic objects for PostgreSQL
GiST and GIN Indexes (Very useful for JSON)
Postgres Weekly
Postgres Data
By vongrippen
Postgres Data
- 1,571