PostgreSQLを使う理由(更新5年目)(翻訳)

こんにちは、hachi8833です。今回もCraig Kerstiens氏のPostgreSQL記事をお送りいたします。

概要

原著者より許諾を得て翻訳・公開いたします。日本語情報へのリンクも適宜追加しています。

PostgreSQLを使う理由(更新5年目)(翻訳)

私が5年前に書いた記事は、PostgreSQLを使うべき理由について述べたことでそこそこ注目を集めました。1年後、そのときに書きもらしたことをその後の記事に多数盛り込みました。その多くは今でも通用する内容なので、この記事の後の方でその中からいくつかを再録したいと思います。それにしても、この4〜5年でのPostgreSQLの進歩はめざましく、PostgreSQLを使うべき理由も増える一方です。PostgreSQLが検討に値する素晴らしいデータベースであることを示すためにこの記事にまとめました。

1. データ型(JSONBや範囲型を含む)

PostgreSQLは長期に渡って、データ型を追加することについてオープンかつ友好的な態度を崩していません。最近だと配列型や地理空間(geospatial)といったものもあります。数年前に導入された次の2つのデータ型は検討に値します。

JSONB

JSONBはJSONのバイナリ表現であり、GINインデックスやGiSTインデックスを使ってインデックス化できます。完全なJSONドキュメントに対してクエリを実行し、簡単に探索することもできます。

範囲型

JSONBの評判の陰に隠れがちですが、範囲(range)型は用途にはまると非常に有用です。1つのカラムの中で、ある値から別の値までの範囲を取れます。これは、範囲が期間の場合に特に便利です。カレンダーを扱うアプリや、開始時刻や終了時刻などのタイムスタンプをよく扱う場合、範囲型なら1つのカラムに保存できます。

範囲型は、特定のタイムスタンプで重複を禁止するなどの、アプリで必要な制約を与えるときに真の力を発揮します。

2. PostgreSQL拡張

PostgreSQLについて語るときには、PostgreSQLを取り巻くエコシステム全体に言及しないわけにはいきません。PostgreSQLの拡張(extension)は、コミュニティやPostgreSQLの成長を促す鍵として、その重要性を増しています。拡張によって、PostgreSQLのコアのコミットに影響を与えることなくネイティブにフックをかけられます。このため、PostgreSQLのリリースサイクルやレビューサイクルに影響を受けない豊富な機能を追加できます。その中からいくつかご紹介しましょう。

Citus

私の働いているCitusではPostgreSQLを分散データベースに変え、複数ノードに渡ってデータベースを容易に共有できるようにしています。この分散データベースはアプリ側から単体のデータベースとして扱えますが、その背後では多くの物理マシンとPostgreSQLインスタンスに分散しています。

HyperLogLog

HyperLogLog拡張は個人的にとても気に入っています。集約済みのCOUNT(DISTINCT)とほぼ同等のことを簡単に行える一方、UNIONINTERSECTIONといったさまざまな操作も自由に行なえます。HyperLogLogなどのスケッチアルゴリズムは大規模データセットや分散システムで広く普及していますが、PostgreSQLならこうした機能をほぼ即座に使えるのが実に嬉しい点です。

訳注: Citus Data社ブログのEfficient rollup tables with HyperLogLog in Postgresも参考になります。

PostGIS

PostGISには長い歴史がありますが、その有用性から近年再び注目を集めています。PostGISは最も高度な地理空間データベースとして知られています。PostGISでは高度な地理空間用途向けのデータ型や演算子が新しく追加され、地図や経路を扱う際に位置ベースでさまざまな操作を簡単に行なえます。

3. 論理レプリケーション

長い間、PostgreSQLで突き当たる壁の中で最も大きかったのは、レプリケーションの設定の難しさでした。元々どの種類のレプリケーションも難しかったのですが、後にストリーミングレプリケーションも加わりました。ここではバイナリWAL(write-ahead-log)形式のストリーミングのことです。

wal-eなどのツールを使うことで、PostgreSQLの障害復旧機能の多くを支援できます。

ここ最近のリリースによって、論理レプリケーションの土台が固められましたが、PostgreSQL拡張(pglogical)が必要だったため、いつでも使えるという状態ではありませんでした。それから後、ついに論理レプリケーションが完全にサポートされました。論理レプリケーションを行うと実際にはいくつかのコマンドを送信し、特定のデータベースや特定のテーブルのみをレプリケーションできます。

4. スケールアウト

PostgreSQLは使い勝手が向上しただけではなく、パフォーマンスについても繰り返し改善されています。特にパラレルクエリのおかげで、クエリによってはパフォーマンスが著しく向上しています。

シングルノードのPostgreSQL(例: RDS上やHerokuでのRAMが122〜244GB)をさらにスケーリングしたいのであれば、スケールアウト面で前述のCitusなどの力を借りる方法もあります。

5. 豊富なインデックス機能

PostgreSQLでは以前から相当強力なインデックス機能を利用できます。GINインデックスとGiSTインデックスはJSONBで有用です。そしてk-近傍(KNN: K nearest neighborhood)インデックス、SP-GiSTなども登場しています。

6. UPSERT

UPSERT(訳注: UPDATEINSERTの造語)についてはかれこれ数年ほど作業が続いています。これはCTE関連で多くのハックが行われた機能のひとつですが、競合状態が発生する可能性がありました。PostgreSQLよりMySQLの方が上回っている機能はいくつかありましたが、UPSERTもそのひとつでした。そして、1年かそこら前になってUPSERTがPostgreSQLでも公式にサポートされました

7. 外部データラッパー(FDW)

外部データラッパー(FDW)は実はずいぶん前からありました。外部データラッパーに詳しくない方のために説明すると、外部のデータシステムをPostgreSQLのテーブルに直接マッピングする機能です。これはたとえば、Redisデータベースとのクエリのやり取りを、PostgreSQL上でSQLを使って直接行えるということです。

5年以上も前に登場してからというもの、外部データラッパーは繰り返し改良され続けています。特に書き込み可能な外部データラッパーによって、外部システムにPostgreSQLから直接データを書き込むことができます。

現在は、PostgreSQL公式の外部データラッパーもあるので即座に利用できます。さまざまなPostgreSQLインスタンスに対してクエリを実行するときにはかなり便利です。

8. その他もろもろ

2012年に公開した「PostgreSQLを使う理由」記事をご覧になったことのない方は、ぜひそちらもどうぞ。以下を含むトピックを扱っています。

  • ウィンドウ関数
  • 関数
  • カスタム言語(PLV8を試してみた方はいますか?)
  • NoSQLデータ型
  • カスタム関数
  • CTE(共通テーブル式)
  • インデックス作成の多重化
  • トランザクションDDL
  • 外部データラッパー
  • 条件インデックスと関数的インデックス
  • Listen/Notify機能
  • テーブルの継承
  • トランザクション単位の同期的レプリケーション

関連記事(PostgreSQL)

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ