My blog

Add intelligent tagline here

[postgresql]PostgreSQL hstoreでKVS

それPostgreSQLでできるよ、第二弾。

PostgreSQLにはhstoreという拡張があります。

これはkeyとvalueの対の集合を単一のレコードに格納することが出来るものです。 つまり、Key-Value-Storeですね。 これを使うと通常のテーブルのようにキーを事前に定義しておく必要がありません。

hstoreについては以下の資料をみてください。特に後者は今回書いていない、いろいろな演算子・関数を紹介していますのですごく参考になります。

そして、今回の記事はherokuのこの記事を元にしています。

herokuはpostgresユーザなんですよ。

hstoreを入れる

hstoreはcontribに入っています。今回はFreeBSDを使用したので、以下のように入れます。

% sudo portinstall databases/postgresql91-contrib

続いてDBにhstoreを入れます。9.1から簡単に拡張を入れられるようになりました。

% psql test -c "CREATE EXTENSION hstore;"

さて、これでhstoreを使う準備は出来ました。

hstoreのテーブルを定義

さっき定義する必要ないって言ってたじゃん、という声もありますが、hstoreという部分だけは定義する必要があります。 といっても、hstoreの中身を定義する必要はありません。

CREATE TABLE products (
  id serial PRIMARY KEY,
  name varchar,
  attributes hstore
);

今回はこうしてみました。herokuのblogのとおりですね。

データを入れる

INSERT INTO products (name, attributes) VALUES (
  'Geek Love: A Novel',
  'author    => "Katherine Dunn",
   pages     => 368,
   category  => fiction'
  );

データを入れるには key => value という構文を使 います。文字列は”で囲むと空白、=、>という記号も入れられます。

検索する

SELECT name as device
FROM products
WHERE attributes->'category' = 'fiction'

検索時はkeyを -> で指定します。

また、”?”を使うことで続く値がキーとしてあれば、という意味になります。

SELECT name, attributes->'pages'
  FROM products
  WHERE attributes ? 'pages'

その他

indexも作れます。

CREATE INDEX product_manufacturer
ON products ((products.attributes->'manufacturer'));

ただ、汎用転置インデックスのGINを使ったほうがいいという話もあります。

joinもできます。

SELECT manufacturers.country, products.name
FROM products, manufacturers
WHERE products.attributes -> 'manufacturer' = manufacturers.name;

今日はここまで

というわけで、PostgreSQLを使うと、こういう便利なことができるよ、という紹介でした。

次のネタに続く…