스크립트
00:00:00「すべてにおいてPostgresを使え」と言い続けてきた開発者たちは、
00:00:04グラフクエリのネイティブサポートが含まれるPostgres 19の次期リリースによって、さらに正しさを証明することになります
00:00:10これは本当に素晴らしい機能です。本日の動画では、Postgres 19の主要な新機能を取り上げ
00:00:16特にグラフクエリについて詳しく見ていきたいと思います。というのも、この機能は
00:00:21クエリの設計方法やPostgresの使い道を根本から変える可能性があると考えているからです
00:00:30まず最初の機能は、「on conflict do select」と呼ばれるものです。行が存在しない場合にのみ挿入し
00:00:35いずれにせよその行を結果として返したい場合、通常は
00:00:40INSERTとSELECTの2つのクエリが必要でした。これは非常に一般的なワークフローです。ここで例として
00:00:45usersテーブルのemailとnameに挿入し、それらの値を渡すとします。そして最後に
00:00:50「on conflict for email do nothing returning star」と指定します。do nothingは、行がすでに存在する場合に何も返さないため
00:00:56その後にSELECTを続けることになりますが、これらを合わせてもアトミックではありません。19ではこれが
00:01:03たった1つのクエリで実行できるようになります。「insert into users」にemailとnameを渡し、「on conflict email do select」と指定して
00:01:11「returning star」と記述します。同じクエリ内で変更を行いたい場合は、再度「insert into users」と値を指定し
00:01:16メールの競合時に「do select for update returning id and name」と記述できます。単一のステートメントであるためアトミックであり
00:01:23毎回挿入または取得のいずれかが確実に行われます。これは非常によくあるユースケースであり、非常に便利になるでしょう
00:01:29続いてはグラフ機能ですが、この内容が気に入っていただけたなら
00:01:34Better Stackに登録して、最新のテック情報をチェックしてください。さて、先ほども言ったように
00:01:39これが私にとって最大の目玉機能です。例えば、ショップ用の一般的なスキーマがあるとします。顧客、注文、商品があり
00:01:44それらを結びつける2つの結合テーブルが存在します。ある顧客が実際にどのお買い物をしたのかを知りたい場合
00:01:50SQLでは5つのテーブルすべてをまたぐ一連のJOINが必要になります。この規模ならまだ管理できますが
00:01:56より複雑な関係になると、すぐに非常に厄介なことになります。しかし今や私たちは
00:02:02これらすべてをグラフとしてクエリできるようになり、複雑なJOIN構文の代わりに新しいグラフ構文を使用できるようになりました。そして
00:02:08特に複雑な結合において、非常に大きなメリットを実感できるはずです。それではデータベースビューアに移動して
00:02:14すべてのテーブルを確認してみましょう。商品、注文、イベント、そして
00:02:20顧客が存在し、さらにこのデータを接続するためのピボットテーブルがあります。注文アイテムと
00:02:25顧客注文があります。それでは、これらすべてのテーブルに対してクエリを実行してみましょう。例えば
00:02:30ここに「アリス」というユーザーがいて、アリスが注文したすべてのアイテムを把握したいとします。これを行うには
00:02:35すべてのテーブルを接続するために、さまざまなJOINクエリを組み合わせる必要があります。そこで、次のようなクエリを実行します
00:02:41このクエリには4つの個別のJOIN文が含まれています。これは必ずしも書くのが難しいわけではありませんが
00:02:46非常に見苦しいものです。しかし実行してみると、アリスが注文したすべてのアイテム
00:02:51メカニカルキーボードやエルゴノミックマウスを確認できます。しかし、グラフ構文を使用すれば、これを劇的に簡素化できます
00:02:57これらすべてを新しいグラフ構文に置き換えて再度実行すると
00:03:03同じ結果が得られます。コードを並べて整理すると、より読みやすくなっていることがわかります
00:03:07顧客から顧客注文、注文、注文アイテム、そして商品へと進んでいるだけであることが確認できます
00:03:13つまり、この単純な流れに従うだけでグラフ全体をたどることができ、私の意見でははるかに読みやすくなっています
00:03:19複数のカラムを選択したい場合も同様に行うことができます。一番上に同じ
00:03:23グラフクエリを配置し、下部でカラムを定義して、表示したいすべてのカラムを選択します
00:03:27実行すると、下部に結果が表示されます。さて、これらはすべて
00:03:32最初にグラフを作成していないと機能しません。そのグラフを生成するために私が使用したクエリは次のとおりです
00:03:37「create propertygraph」と記述し、名前として「my shop」を与え
00:03:42頂点テーブル(vertex tables)として顧客、注文、商品を定義します。これらは実際にデータを保持するものです
00:03:47そしてエッジテーブル(edge tables)を定義します。これらは実際に接続を行うもの
00:03:52つまりピボットテーブルです。今回のケースでは、それは顧客注文と注文アイテムになります
00:03:57構文は非常にシンプルで、顧客注文については、ソースが顧客で
00:04:02宛先が注文であり、注文アイテムについては、ソースが注文で宛先が商品であると指定します
00:04:08これを行うことで、グラフクエリを実行するたびに、Postgresはそれらの関係がどのように定義されているかを認識できるようになります
00:04:14これを機能させるにはグラフを作成する必要がありますが、新しいテーブルなどが作成されるわけではありません
00:04:19すでに持っている5つのテーブルを指定するだけです。データを保持する3つのテーブルが
00:04:23頂点となり、2つの結合テーブルがエッジになります。ビューに非常に近い動作をするため、これまでのスキーマは
00:04:29一切変更されず、その上にこの追加機能が提供されるだけです。ここでは
00:04:35「create property graph」と記述して「my shop」と名付け、その関係がどのように
00:04:40機能するのかを記述していきます。ここでグラフに関するすべての処理を行っており、結果としてクエリを
00:04:45それぞれのJOIN構文よりもはるかに簡潔にすることができます。では、これはNeo4jの代替となるでしょうか?もし
00:04:52グラフストレージやトラバーサル性能の理由でグラフデータベースが必要な場合、答えはノーであり
00:04:58専用のグラフデータベースの方が依然として良い選択肢です。しかし、SQLで10個のテーブルのJOINを書くのが
00:05:03面倒で醜いためこれが欲しいのであれば、間違いなくメリットがあり、比較にならないほど快適になるでしょう
00:05:093つ目の新機能は「recap」であり、これはディスク容量を取り戻すためのものです。Postgresは
00:05:15行をその場で更新することはなく、新しいバージョンを書き込んで古いものを残します。そしてVACUUMは
00:05:21そのデッドスペースを再利用可能としてマークするだけなので、ディスク使用量が実際に減ることはありません。repackはテーブル全体を
00:05:27無駄なスペースを一切含まない新しいファイルに書き直します。それによってオペレーティングシステムに容量が返されます
00:05:33「VACUUM FULL」を使えばすでに似たようなことはできましたが、それは書き換えの間テーブル全体を
00:05:38ロックしてしまいます。そのため、大規模なものに対しては実行できませんでした。それが、人々が
00:05:42「pg_repack」のような拡張機能をインストールしていた理由です。しかし現在ではPostgresに直接組み込まれており
00:05:49これに「concurrently」キーワードを使用すると、repackの実行中もテーブルの読み書きを維持できます
00:05:54ただし注意すべき点として、テーブルとそのすべてのインデックスの2つ分のコピーを収めるだけの十分な空きディスク容量が必要です
00:06:00つまり、スペースを回収するために予備のスペースが必要になります。そのため、これはpg_repackの完全に正確な代替品ではありませんが
00:06:06通常のテーブルであれば、拡張機能なしでその役割を果たしてくれます。さて、次は
00:06:1119リリースの残りの機能についてのクイックファイアです。最初はクエリヒントです。Postgresはクエリの実際の実行方法を決定しますが
00:06:17時間が経つにつれてその判断が変わることがあります。そのため、1年間問題なく動作していたクエリが突然遅くなり
00:06:22コードは何も変更していないという状況が起きます。「pg_plan_advice」と呼ばれる新しいモジュールにより、高速なうちにプランをキャプチャして
00:06:28固定し、常にその状態を維持できるようになります。JITはデフォルトでオフになりました。Postgresは重いクエリを
00:06:36機械語にコンパイルしますが、プランナのコスト見積もりからいつそれを実行すべきかを判断していました。リリースノートによると
00:06:41そのコスト計算は実際には信頼性が低く、実際には必要のないクエリに対しても実行されていたとのことです
00:06:46また、VACUUMが複数のワーカーで並行してインデックスをクリーンアップできるようになりました。これにより、大規模なテーブルのVACUUMに
00:06:52費やす時間を削減できます。ただし、これ手動で有効にする必要があります。カラムを追加して
00:06:58SELECTを実行し、その後GROUP BYにも同じカラムを追加しなければならないとき、その作業をすべて自動で行ってくれます
00:07:03さらに、COPYキーワードで直接JSONにエクスポートできるようになりました。これまでCSVでダンプして後から変換していたなら
00:07:09もうその必要はありません。これがPostgres 19ベータ2であり、7月にリリースされました。正式リリースは
00:07:159月か10月頃に予定されています。そのため、古いバージョンを実行している場合は、ベータ版をダウンロードして
00:07:21テストしてみる価値があります。Postgresについてさらに詳しく知りたい場合は
00:07:25「pg_durable」の解説をチェックしてみてください。耐久性のあるワークフローをPostgres内に直接構築できます。私はBetter Stackの
00:07:31ウォーレンでした。ご視聴ありがとうございました。次の動画でお会いしましょう