BunのビルトインSQLクライアントを使ってAurora PostgreSQLに接続する
はじめに
JavaScriptランタイムの1つとして知られる Bun
が、バージョン1.2よりSQLクライアントをビルトインするようになりました。
リリース時点ではPostgreSQLのみに対応していますが、将来的にMySQLもサポートする予定とのことです。
この新しい Bun.sql
を使ってAurora PostgreSQLに接続してみました。
Bunのインストール
公式の手順とおりに Bun
をインストールしていきます。
# インストール
$ curl -fsSL https://bun.sh/install | bash
# Bunのバージョンを確認
$ bun --version
1.2.0
今回リリースされた 1.2.0
がインストールされていることを確認できました。
事前準備
Aurora PostgreSQLクラスターを作成しておきます。今回は本筋ではないので手順を省略しますが、バージョンは以下のとおりです。
testdb=> select * From version();
version
-------------------------------------------------------------------------------------------------
PostgreSQL 15.4 on x86_64-pc-linux-gnu, compiled by x86_64-pc-linux-gnu-gcc (GCC) 9.5.0, 64-bit
(1 row)
サンプルコード
Bun.sql
ですが、人気ライブラリの Postgres.js
にインスパイアされているとのことで、使い方はかなり似ています。
スクリプトを書く前に、まずは .env
ファイルを作成します。
DBのホスト名、ポート番号、ユーザ名、パスワード、データベース名といった接続情報を記述します。
PGHOST=xxxxxxxxxx.cluster-yyyyyyyyyyyy.ap-northeast-1.rds.amazonaws.com
PGPORT=5432
PGUSERNAME=admin
PGPASSWORD=****************************
PGDATABASE=testdb
こちらは Bun
のほうでよしなに読み取ってくれます。
あとはスクリプトを書いていくだけです。試しに、テーブル作成・バルクインサート・データ取得、を行うスクリプトを書いてみました。
import { sql } from "bun";
await sql`
CREATE TABLE users (
name VARCHAR(16),
age SMALLINT
)
`;
const newUsers = [
{ name: "Taro", age: 20, },
{ name: "Jiro", age: 30, },
{ name: "Saburo", age: 40, },
];
await sql`
INSERT INTO users ${sql(newUsers)}
`;
const users = await sql`
SELECT name, age
FROM users
`;
console.log(users);
Postgres.js
と同様にテンプレートリテラルを使ってSQLを記述するので、非常に直感的な書き方ができます。
上記のスクリプトを実行すると出力結果は以下のようになります。
$ bun index.ts
[
{
name: "Taro",
age: 20,
}, {
name: "Jiro",
age: 30,
}, {
name: "Saburo",
age: 40,
}, statement: undefined, command: "SELECT", count: 3
]
このように、Aurora PostgreSQLにも問題なく接続でき、データの操作ができました。
Postgres.js
との速度比較
公式の発表では、 Bun.sql
は Postgres.js
よりも高速であるとのことです。早速試してみましょう。
なお、 Node.js
のバージョンは v22.13.1
で、 Postgres.js
のバージョンは 3.4.5
を使います。
前準備
最初に、10万件のダミーデータを作成しておきます。せっかくなので、 Bun.sql
で実行してみます。
const newUsers = Array.from({ length: 100000 }, (_, i) => ({
name: `User${i}`,
age: Math.floor(Math.random() * 100),
}));
// トランザクションを開始
await sql.begin(async tx => {
// 1000件ずつバルクインサート
for (let i = 0; i < newUsers.length; i += 1000) {
await tx`
INSERT INTO users ${sql(newUsers.slice(i, i + 1000))}
`;
}
});
実行時間計測用スクリプト
このデータを取得する際の実行時間を計測、比較してみます。以下のようなスクリプトを用意しました。
import { sql } from "bun";
async function main() {
try{
const randomId = Math.floor(Math.random() * 100000);
const result = await sql`
SELECT name, age
FROM users
WHERE name = ${`User${randomId}`}
`;
console.log('Result:', result);
} catch (error) {
console.error('Error:', error);
} finally {
await sql.end();
}
}
main().catch(console.error);
同様に、 Postgres.js
を使ったスクリプトも用意しました。内容はほぼ同じです。こちらは Node.js
で実行します。
const postgres = require('postgres');
async function main() {
const sql = postgres({
host: process.env.PGHOST,
database: process.env.PGDATABASE,
username: process.env.PGUSER,
password: process.env.PGPASSWORD,
});
try {
const randomId = Math.floor(Math.random() * 100000);
const result = await sql`
SELECT name, age
FROM users
WHERE name = ${`User${randomId}`}
`;
console.log('Result:', result);
} catch (error) {
console.error('Error:', error);
} finally {
await sql.end();
}
}
main().catch(console.error);
結果
Bun.sql
での実行時間は以下のとおりです。3回ほど実行し、その平均に当たる値を採用しました。
$ time bun bun-test.ts
real 0m0.076s
user 0m0.024s
sys 0m0.008s
次に、 Postgres.js
での実行時間を計測してみます。
$ time node --env-file=.env postgresjs-test.js
real 0m0.106s
user 0m0.062s
sys 0m0.018s
単純なクエリのテストなのでこれだけで判断するのは難しいですが、 Bun.sql
のほうが高速であることが確認できました。
おわりに
Bun.sql
を使ってAurora PostgreSQLに接続してみました。これまでよりも若干高速な処理が可能になり、別途ライブラリを用意する必要もなくなったので便利になったかなと思います。とは言え、シンプルゆえに手が届きにくい部分もあるかもしれませんので、 Postgres.js
のような既存ライブラリを使う必要が出てくる場面もまだまだありそうです。
現在も開発が進んでいる段階なので、今後のアップデートに期待です。