I am being required to use a postgreSQL database and it will replace my current use of berkeleyDB. Although; I realize this is not an ideal situation, it is beyond my control.
So the question is... If you were required to make postgreSQL into a key value store how would you go about doing this, while making it as efficient as possible?
My values are byte arrays and my key's are strings, I could impose some restrictions on the lengths of these strings.
I assume I should use a blob for my value and primary key column holding the key, but as I am just venturing into this journey I am curious if anyone in the stack overflow community has done this, or if there are any specific 'gotchas' I should look out for.
Exploring hstore, PostgreSQL's simple key-value store hstore is a PostgreSQL extension that implements the hstore data type. It's a key-value data type for PostgreSQL that's been around since before JSON and JSONB data types were added.
When to use a key-value database. When your application needs to handle lots of small continuous reads and writes, that may be volatile. Key-value databases offer fast in-memory access. For applications that don't require frequent updates or need to support complex queries.
PostgreSQL provides two distinct ways to store binary data. Binary data can be stored in a table using the data type bytea or by using the Large Object feature which stores the binary data in a separate table in a special format and refers to that table by storing a value of type oid in your table.
The extension in Postgresql to properly do this is called hstore. It works in a similar fashion as you would expect other key-value store systems. Just load the extension. The syntax is unique but if you have ever used redis or mongo you will get it quickly. Don't make it harder than it is. I understand, we often don't get to pick our tools and have to make do.
Here is the document page:
http://www.postgresql.org/docs/9.1/static/hstore.html
Another option is to use JSON or JSONB with a unique hash index on the key.
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE key_values (
key uuid DEFAULT uuid_generate_v4(),
value jsonb
);
CREATE INDEX idx_key_values ON key_values USING hash (key);
Some queries
SELECT * FROM key_values WHERE key = '1cfc4dbf-a1b9-46b3-8c15-a03f51dde891';
Time: 0.514 ms
postgres=# SELECT * FROM key_values WHERE key = '1cfc4dbf-a1b9-46b3-8c15-a03f51dde890';
Time: 1.747 ms
postgres=# do $$
begin
for r in 1..1000 loop
INSERT INTO key_values (value)
VALUES ('{"somelarge_json": "bla"}');
end loop;
end;
$$;
DO
Time: 58.327 ms
You can't run efficient range queries like with B-tree, but it should have better read/write performance. Index should be about 60% smaller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With