MySQL 9.0: 純粋なSQLに代わりJavaScriptでストアドプロシージャを記述する

MySQL tutorial - IT technology blog
MySQL tutorial - IT technology blog

MySQL 9.0とJavaScriptがもたらす進化

ストアドプロシージャ(SP)内で純粋なSQLを使用してロジックを処理することは、これまで多くのエンジニアにとって「悩みの種」でした。DECLAREBEGIN...END、あるいはWHILEループといった構文は非常に扱いにくく、デバッグも困難です。以前、1,000万行を超えるordersテーブルを持つECシステムを管理していましたが、SQLプロシージャで階層的な割引計算を行うのは、コードが長く、ミスが起きやすく、メンテナンスが非常に困難で、まさに悪夢でした。

MySQL 9.0では、GraalVMベースのMultilingual Engine (MLE)が統合されました。この変更により、**JavaScript (ECMAScript 2023)**を使用してデータベース内で直接ビジネスロジックを記述できるようになりました。これは単なる新機能ではなく、データをその場で処理するためのよりモダンなアプローチです。

ビジネスロジック処理手法の比較

JavaScriptストアドプロシージャにアップグレードする価値があるかどうかを判断するために、一般的な3つの手法を比較してみましょう:

1. アプリケーション層での処理 (Node.js, Python, Go…)

  • メリット: ユニットテストが書きやすく、膨大なライブラリエコシステムを活用できる。
  • デメリット: ネットワーク経由でDBからアプリへデータをプルする必要がある. 1つの集計値を得るために500MBのデータを処理する場合、レイテンシによってシステムが大幅に低速化する。

2. 従来のSQLストアドプロシージャ

  • メリット: DB内で直接実行されるため、データ転送のリソースを消費しない.
  • デメリット: 構文が古く、文字列やJSONの処理が非常に困難で、コードの再利用性が低い。

3. JavaScriptストアドプロシージャ (MySQL 9.0+)

  • メリット: JSのパワー(スムーズなJSON処理)とインプレース(その場)実行のパフォーマンスを兼ね備えている。
  • デメリット: 現在はMySQL 9.0 Enterpriseまたは最新のCommunity版のみ。GraalVMを使用するため、適切なRAMの割り当てが必要。

なぜJavaScriptへの移行を検討すべきなのか?

データベースにJSを導入することを決めた3つの理由は以下の通りです:

  1. 直感的なJSON操作: JSはJSONを扱うために生まれてきました。SQLでは煩雑なJSON_EXTRACT関数を使う必要がありますが、JSでは通常のオブジェクトのようにプロパティにアクセスできます。
  2. モダンな構文: mapfilterreduceを使ってデータセットを処理できます。これらの関数により、古めかしいSQLのループ処理よりもコードがはるかに簡潔で読みやすくなります。
  3. 豊富なリソース: SQLプロシージャの最適化エキスパートを探すよりも、JSに精通した開発者を探す方がはるかに容易です。

実践的な導入ガイド

開始する前に、SELECT VERSION();コマンドでMySQLのバージョンを確認してください。以下の例を実行するにはバージョン9.0が必要です。

ステップ1:最初のJavaScriptプロシージャを作成する

環境を確認するために、簡単なプロシージャを試してみましょう:

CREATE PROCEDURE hello_js(IN name TEXT) 
LANGUAGE JAVASCRIPT AS $$
  // こんにちは {name}さん、MySQLでJSが動作しています!
  console.log("Chào " + name + ", JS đang chạy trong MySQL!");
$$;

通常のプロシージャと同様に呼び出して実行します:

-- ITエンジニアの皆さん を引数に渡して実行
CALL hello_js('Anh em IT');

ステップ2:実際のビジネスロジックの処理

JSON形式のdetailsカラムを持つproductsテーブルがあると仮定します。タスクは、ステータスが “active” の商品の総在庫額を計算することです。

CREATE PROCEDURE calculate_inventory_value(OUT total_value DOUBLE)
LANGUAGE JAVASCRIPT AS $$
  let results = session.sql("SELECT details FROM products").execute();
  let total = 0;
  
  results.fetchAll().forEach(row => {
    let details = JSON.parse(row[0]);
    if (details.status === 'active') {
      total += (details.price * details.stock);
    }
  });
  
  total_value = total;
$$;

session.sql()オブジェクトは、DBとの架け橋の役割を果たします。この書き方はバックエンドでDBドライバを使用する感覚に非常に近く、開発者が文脈の切り替えで戸惑うことはありません。

実戦経験:いつ適用すべきか?

JSは非常に強力ですが、データベースをロジックの「ゴミ捨て場」にしてはいけません。以下の基準を考慮してください:

推奨されるケース:

  • 大規模なJSONデータに対して、複雑なロジックをその場で処理する必要がある場合。
  • SQLでのサポートが不十分な計算処理や正規表現(Regex)を使用する場合。
  • 複数のサービス(PHP、Go、Pythonなど)で共通の計算結果を利用するためにロジックをカプセル化したい場合。

避けるべきケース:

  • 単純なCRUD操作を行う場合。依然として純粋なSQLが最速の選択肢です。
  • サーバーのCPUやRAMがすでに過負荷な場合。GraalVMエンジンの起動には追加のシステムリソースを消費します。

セキュリティとパフォーマンスに関する注意点

セキュリティは最優先事項です。SQLインジェクションを防ぐため、文字列の結合は絶対にしないでください。パラメータを安全に渡すには、常にsession.sql().bind()を使用してください。

パフォーマンスに関しては、100万レコードのテーブルでテストを行いました。JSプロシージャによるJSON処理は、SQLのJSON_EXTRACT関数を使用する場合よりも約30%高速でした。JS의 ネストされたデータ構造の最適化能力により、処理時間は12秒から約8.5秒に短縮されました。

MySQL 9.0でのJavaScriptの登場は、データベースとアプリケーションコードの境界を縮めます。新しいプロジェクトを開始する場合は、この機能を活用してデータ処理プロセスを効率化することを検討してみてください。

Share: