ども、@kimhom です。
今回は必要に駆られて PostgreSQL で新しく登場した JSONB 型について調べるきっかけがあったので、まとめてみる。
予め断っておくと JSONB 型はいわば PostgreSQL のリレーショナルデータベースからの脱却だ。これは一見魅力的に見えるけど、誰もが待ち望んだ機能というわけではない。導入するときは慎重に検討するようにしたいところだ。
なぜ JSONB 型が必要になったか
特に SaaS のアプリケーションを作っている方なら共感してくれると思うのだけど、保存したいデータが顧客によって異なるというケースが否応にしてある。例えば 顧客管理のサービスを扱っているなら、業界ごとに保存しなければならない項目(本記事ではカスタム項目と呼ぶ)は異なってくるし、逆に不要な項目なども出てくることだろう。そんな中、最もやってはいけない妥協が、とりあえず全ての項目を表示させるってやり方だ。これだと、機能がどんどん複雑になっていってしまって、誰のためのサービスなのかわからなくなってきてしまう。しかし、従来のリレーショナルデータベースでの設計であれば、それが正攻法だったし、リレーショナルデータベースとしての正しい使い方でもあったわけだ。
カスタム項目を最初にうまく実現したのは Salesforce だろう。そのあと、kintone のようなクラウドデータベースや、Hubspot などのカスタマイズ可能な CRM などが出てきている。最近では Zendesk や Intercom も同様のカスタム項目を提供するようになってきた。お分かりの通り、もはやカスタム項目は SaaS をより拡張して誰もが最適なアプリケーションになるために必須となりつつある技術である。
PostgreSQL には、従来より hstore と呼ばれる Key/Value で保存されるデータ形式が提供されていた。しかし、これではネストができなかったり、インデックスが効かなかったりとで不自由なことが多かった。そして最近 PostgreSQL には JSON 型が出てきたわけだけども、これはこれで圧縮されていないためデータ効率が悪かったり、インデックスが効かないというデメリットがあった。それらを解決し、カスタム項目といった柔軟なデータベース設計ができるようにするために、JSONB 型ってのが登場してきた。
カスタム項目を作りたい人は、従来はそのほかのデータベース(MongoDBなど)を選択することになっていたと思うが、これからは NoSQL のような柔軟性を兼ね揃えた PostgreSQL でも実現可能ということになる。もっとこれはビッグニュースになっていいと思うんだけど、あまり注目はされていない? ようなのでもうちょっと詳しく書いていく。
JSONB 型の利用
Great News。 Rails 4.2.5 からは JSONB 形式が標準でサポートされている。その他主要な Web アプリケーションフレームワークでも、今後サポートされていくことだろう。
def change create_table :model do |t| t.jsonb :payload # ..... end add_index(:model, :payload, using: 'gin') end
この GIN インデックスってのが JSONB 用のインデックスだ。今までこのようなカスタム属性用のインデックスはなかったので、新しいデータ活用が見込めるだろう。このインデックスの詳細は他で調べてみていただきたい。
んで肝心の JSONB データのアクセスなんだけど、以下のような新しい記法を目にすることになるだろう。
->
JSON のオブジェクトフィールド名や配列インデックスを指定し、その値をJSONB型で取得->>
JSON のオブジェクトフィールド名や配列インデックスを指定し、その値をTEXT型で取得#>
は階層パスを指定して その値をJSONB型 で取得#>>
は階層パスを指定して その値をTEXT型 で取得
最近の PostgreSQL では JSON の特定の Key/Value を更新することができるようになったし、保存された JSON を each してくれるような SQL 構文も用意されている。なんだかんだ PostgreSQL の JSON サポートしてから 2年くらい経つようである。調べてみると、次の PostgreSQL は Version 10 らしく、メジャーアップデートが控えているようなので、そこまで様子を見守りたいところでもある。
参考リンク
以下の記事はお世話になったので、より詳細を知りたい方はぜひ読んでみて、可能性を感じてほしい。
- PostgreSQL JSON型についての使い勝手とパフォーマンス、時々ハマりどころの調査 - Qiita
- PostgreSQL 9.3 の JSON サポートについて(長いよッ) - Qiita
- PostgreSQL 9.4 の JSON サポートについて - Qiita
- PostgreSQL JSON の応用メモ - Qiita
特に最後のリンクのユースケースは、どのような応用ができるのかを挙げていただいていて参考になった。
終わりに
ちなみに Heroku Postgres はすでに 9.6 をサポートしているので、この JSONB 型を自由に扱うことができる。
こういうインフラストラクチャレベルの新機能ってのは、新しい機能を持ったサービスが出てくる予兆だと思う。ぜひこの JSONB 型を使って何か素晴らしいサービスが作れないか、考えてみてはいかがだろうか。その機能ってのは、きっと今まで実現困難だった何かであるはずで、新規性という意味で差別化できることだろう。私はどっちかっていうとフロントエンドエンジニアだけど、久々にデータベースを勉強してワクワクしたものを見つけた気分である。
さぁって、私も設計を始めるとしよう。