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

こんにちは、hachi8833です。今回もCraig Kerstiens氏のPostgreSQL記事をお送りいたします。 概要 原著者より許諾を得て翻訳・公開いたします。日本語情報へのリンクも適宜追加しています。 元記事: Why Use Postgres (Updated for Last 5 Years)(2017/04/30) 著者: Craig Kerstiens: PostgreSQLのクラウドスケーリングサービスで知られるCitus Dataのメンバーであり、Herokuにも在籍したことがあります。 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)とほぼ同等のことを簡単に行える一方、UNIONやINTERSECTIONといったさまざまな操作も自由に行なえます。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(訳注: UPDATEとINSERTの造語)についてはかれこれ数年ほど作業が続いています。これは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) PostgreSQLの機能と便利技トップ10(2016年版)(翻訳) Rails開発者のためのPostgreSQLの便利技(翻訳) [Rails] RubyistのためのPostgreSQL EXPLAINガイド(翻訳) 【ゆるふわDocker部】任意バージョンのPostgreSQLコマンドを実行して外部DBに接続する RailsでPostgresを使おうとしてはまった