sqlPostgreSQL9.2以降のバージョンではjson型/jsonb型カラムが使える。特殊な記法を使うけど、json/jsonbデータ内のキーをDBのカラムと同様に使えるようになるので、スキーマレスDBのように同じテーブル内のレコードで異なるデータ構成を持たせることができるようになる。役に立ちそうなので触ってみた。環境はPostgreSQL9.5。公式ドキュメントのjson/jsonb型カラムに関する情報は下記のページに記載されている。集約関数JSONB型カラムを持つテーブルを作成するサンプルとして商品情報を登録するテーブルを作成してみる。公式ドキュメントによると、登録するJSONデータのマップキーの順序をどうしても守りたい事情でもない限り、JSONB型カラムを使うのが良さそうなので、JSONB型カラムを使う。key(id));比較用に、通常のカラムを利用する商品テーブルとJSONB型カラムを使う商品テーブルを両方作っておいた。createdがjsというJSONB型カラムに入る想定。続いて、データを登録する。速度も確認したいので、generate_series関数を使って10万件ずつデータを入れてみる。i;JSONB型カラムにはjsonb_build_objectという関数を使って生成したJSONBデータを登録してる。i;PostgreSQLの関数を使ったりする時はjsonb_build_object関数を使う方がスッキリ書ける。10万件のデータを登録するくらいでは速度面では通常カラム版とJSONBカラム版に大きな違いはなかった。(ちゃんと測ってない)検索ここからはJSONB型テーブルで色々試してみる。JSONB型カラム内のテキスト、数値、boolean型のデータでそれぞれ検索する方法。10;JSONB型カラムで不便なのが、データの取得をJSONB型かテキスト型でしか直接取得できないこと。JSONB型でデータを取得する場合はカラム名->'キー名'と書き、テキスト型で取得する場合はカラム名->>'キー名'と書く。大なり記号が1つか2つかのちがい。文字列等のデータを取得する場合に文字列型での取得を利用するものと思われる。文字列として取得してから型変換する必要がある。続いて、インデックスがどう使われるかを試してみる。違いが出そうな数値型データ(ここではpriceデータ)を使って確認する。jsonb_test_jsonb_items(((js->>'price')::numeric));price列に対してJSONB、テキスト、numeric型変換版の3種のインデックスを登録した。analyzeしてみる。10;結果、1のクエリはインデックスが使用されず、2のクエリは「idx_jsonb_test_price_text」を使用し、3のクエリは「idx_jsonb_test_price_numeric」を使用してた。数値型キーをインデックス登録する際は#3のようにnumeric型だと明示してインデックスを登録しておく必要がありそう。データを更新する続いて、JSONB型カラムのデータを更新してみる。既存データのUPDATE方法について調べる。基本的にJSONB型カラムはテーブルカラムとしては1つのカラムなので、JSONデータ内の個別更新ではなく、一括更新が基本となっている。一応「jsonb_set」という、キーを指定して値を更新できる関数は用意されているが、このキーとこのキーとこのキーの値を更新する、みたいな時には使いづらそう。いえ、いちいち元のデータを取得してから必要な値を変更して更新するのも面倒なので、変更したいキーと値のセットを渡すだけで他のキーの値を維持して更新できるマージ方法はないか、と探してみたら「||」演算子があった。「||」演算子はJSONB型データを結合し、同じキーを持ったJSONを結合すると後で渡した値を優先してマージしてくれる。下記のようなUPDATE文を書くのが一番ラクそう。'0000000001';こうすると、元のjsの「name」キーの値が「新しい名前」で上書きされる。下記のように存在しないキーを指定すると、キーが追加される。<キー名>」で削除できる。'0000000001';これで上で追加した「name2」キーが削除される。01:30JSONB型カラムでPostgreSQLをNoSQL風にスキーマレスに使う方法Tweet関連記事2018-08-17node.jsでWebスクレイピングして取得データを保存するnode.jsでデータ収集のためのWebスクレイピングを行う。はてなブログProおいしいものを食べてぐーたらすることしか考えていない、2児の父。noteにもエッセイを載せてます。Versionnoteはてなブログをはじめよう!piro_sukeさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。