Announcing D1: Our first SQL database

当社は2017年にCloudflare Workersを発表しました。これは、当社のネットワーク上のコンピューティングへのアクセスを開発者に提供するものです。私たちは、このことによって生まれる可能性に胸を躍らせていましたが、すぐに、現実世界のほとんどのアプリケーションはステートフルであることに気づきました。それ以来、私たちはKV、Durable Objects、R2を提供し、開発者がさまざまなタイプのストレージにアクセスできるようにしました。

本日、当社では初のSQLデータベースである「D1」を発表できることを大変嬉しく思います。

ベータ版をご利用いただけるまで、あとわずかとなっております。早ければ6月頃から開始する予定で(ご登録はこちらから)、今後の詳細について皆さんにお伝えしたいと思います。

D1との出会い、Cloudflare Workers用に設計されたデータベース

D1は、SQLiteをベースに構築されています。SQLiteは世界で最もユビキタスなデータベースで、1日に何十億ものデバイスで使用されているだけでなく、史上初のサーバーレスデータベースでもあるのです。驚かれたでしょうか?SQLiteは時代を先駆けており、クラウドサービスの意味合いが強くなる前に自らを「 サーバーレス」と呼びました。もともとは文字通り「サーバーを介さない」ことを意味していたのです。

Workers自体がサーバーとクライアントの間で動作し、クライアント用に作られた技術にインスパイアされているため、SQLiteは当社の導入する最初のデータベースとして最適であると考えた結果です。

では、D1を使用するとどのようなものが作れるのでしょうか?言ってしまえば「ほとんど何でも!」ですが、それでは想像力をかき立てられないかもしれませんので、ライブデモをご紹介したいと思います。

D1デモ:ノースウィンドトレーダーズ

D1の動作例は、こちらのデモをご試用いただきご確認ください:northwind.d1sql.com

「ノースウィンドトレーダーズって誰?」という方へ説明すると、ノースウィンドトレーダーズとはデータベースの「Hello, World!」と言えばお判りでしょうか。マイクロソフトが自社のチュートリアルとして、Microsoft Accessと一緒に提供するサンプルデータベースです。最初に登場したのは25年前の1997年ですが、インターネット上に数多くの使用例が存在します。

これは典型的なビジネスアプリケーションで、現実的なスキーマ、多くの外部キーがあり、それらが多くの異なるテーブルにまたがる、どの時代でも使用するデータ表現です。

「最近注文したケソ・カブラレス・チーズがいつ、どの船で出荷されたのか?」「チャイの注文について問い合わせがあったか?」「エキゾチック・リキッドはまだ39個の在庫があり、それぞれ18ドル。」などの情報を、すぐに知ることができます。

是非遊んでいただき、あらゆる角度から使用してみてください。ノースウインドトレーディングのビジネスに関するあらゆる疑問にお答えします。

また、ノースウィンドトレーダーズのデモにはダッシュボードもあり、バックグラウンドで発生しているD1のSQLクエリの詳細や指標を確認することもできます。

D1を使用すると何が作れるのか?

デモ前の最初の質問に戻りますが、D1を使用すると何が作れるのでしょうか?

あなた自身、ノースウインドトレーディング社を自分で経営しているわけではありませんが、どこかで非常に似たようなソフトウェアを運営している可能性があるのではないでしょうか。Cloudflareのサービスの中核にあるものでさえ、データベースです。数々のテーブル、マテリアライズドビュー、ストアドプロシージャがあふれているSQLデータベースです。お客様が当社のダッシュボードを操作するたびに、そのデータベースの状態は変化します。

実世界の中で、データベースはあらゆるところに存在しています。今この記事を読んでいるWebブラウザの中にも、スマートフォンのあらゆるアプリの中にも、銀行取引、旅行予約、業務用アプリケーションのストレージにも、データベースは存在します。D1の目標は、電子商取引サイト、会計ソフト、SaaSソリューション、CRMなど、APIからリッチでパワフルなアプリケーションまで、あらゆるものの構築に貢献することです。

D1とCloudflare Accessを組み合わせて、組織内のユーザーだけが利用できる安全にロックされた内部ダッシュボードや管理ツールを作成することもできます。まさに、あなたの可能性は無限大です。

D1の開発者エクスペリエンス

この記事では、D1が持つ能力と今後の機能について詳しく説明しますが、その中核にあるD1の強みは開発者エクスペリエンスです。D1を使用することで、何もない状態から完全なスタックアプリケーションに瞬時に移行できるのです。魔法のように開発ができるツールを使った時のことを思い出してください。これこそが、まさにWorkersとD1を使った開発で感じてもらいたいことなのです。

それを実感していただくために、次にご覧いただくようにD1を始めていきます。

最初のD1データベースを作成する

D1では、わずか数回のクリックでデータベースを作成することができ、その内容はテーブルの定義、データの挿入やアップロードを行うのみです。必要な場合以外はコマンドを覚える必要はありません。

もちろん、コマンドラインがお好きな方向けに、今週初めに新しく改良されたWrangler 2を発表しています。これは、Workersのラングリングとデプロイのための最高のツールで、また、すぐにD1のデプロイするためのツールになります。WranglerにはD1のネイティブサポートも含まれ、いくつかの簡単なコマンドでデータベースを作成、管理することができます。

WorkerからD1にアクセスする

WorkerへのD1の接続は、新しいバインディングを作成するのと同じくらい簡単です。Workerに接続する各D1データベースは、envパラメータに独自のバインディングで接続されます。

export default {
  async fetch(request, env, ctx) {
    const { pathname } = new URL(request.url)
    if (pathname === '/num-products') {
      const { result } = await env.DB.get(`SELECT count(*) AS num_products FROM Product;`)
      return new Response(`There are ${result.num_products} products in the D1 database!`)
    }
  }
}

また、もう少し複雑な例では、Routerとパラメータ付きクエリを使用して、URLからデータベースへ安全にパラメータを渡すことができます。

import { Router } from 'itty-router';
const router = Router();

router.get('/product/:id', async ({ params }, env) => {
  const { result } = await env.DB.get(
    `SELECT * FROM Product WHERE ID = $id;`,
    { $id: params.id }
  )
  return new Response(JSON.stringify(result), {
    headers: {
      'content-type': 'application/json'
    }
  })
})

export default {
  fetch: router.handle,
}

D1に期待できることは?

何よりもまず望むことは、お客様がコストを気にすることなくD1で開発いただくことです。

Cloudflareでは、お客様のデータを人質に取るようなことは考えておらず、D1もR2と同様に従量課金はありません。D1の価格は、ストレージ製品の価格と同様に、基本ストレージに加え、データベースの操作に対する課金を予定しています。

しかし、繰り返しになりますが、私たちは、お客様がコストを心配したり、ビジネスが軌道に乗って、より多くのストレージやアクティビティが必要になった場合にどうなるかを心配するようなことは望んでいません。私たちは、お客様が思いつく限りのシンプルなアプリケーションも複雑なアプリケーションも構築できるようにしたいと考えています。私たちは、D1が、どの同等の集中型ソリューションよりも低コストかつ優れたパフォーマンスを持つことを保証します。サーバーレスとCloudflareのようなグローバルネットワークが約束するのは、私たちのアーキテクチャによるパフォーマンスと、よりコストを抑えることです。

ここでは、D1での機能を少しご紹介します。

リードレプリケーション

D1では、アプリケーション全体の状態を一箇所に保存して、データセット全体に対して任意のクエリを実行できるようにしたいと考えています。それが、リレーショナルデータベースの強みです。

私たちは強力であることが面倒であることと同義であるべきだとは考えていません。ほとんどのリレーショナルデータベースは巨大かつモノリシックであり、レプリケーションの設定も簡単ではないため、一般的にほとんどのシステムは、すべての読み込みと書き込みは単一のインスタンスに戻るように設計されています。D1では、これとは異なるアプローチを採用しています。

D1では、お客様の手を煩わせることなく、Cloudflareのグローバルネットワークを活用したいと考えています。D1は、お客様のユーザーの近くにデータの読み取り専用のクローンを作成し、常に変更を反映させた状態で維持します。

バッチ処理

アプリケーション内で行われる多くの操作は、単一のクエリを生成するだけではありません。せっかくロジックがお客様のユーザーの近くのWorkerで実行されていても、これらのクエリがそれぞれデータベース上で実行される必要がある場合、わざわざ1つずつ線を伝って送られるのでは非常に非効率的です。

D1のAPIにはバッチ処理機能があります。単一のSQL文を送信できる場所ならどこでも、それらを配列で提供することもできます。つまり、1回のHTTPラウンドトリップで複数の処理を実行できるのです。これは、アトミックな実行とコミットを必要とするトランザクションに最適です。

async function recordPurchase(userId, productId, amount) { 
  const result = await env.DB.exec([
    [
      `UPDATE users SET balance = balance - $amount WHERE user_id = $user_id`,
      { $amount: amount, $user_id: userId },
    ],
    [
      'UPDATE product SET total_sales = total_sales + $amount WHERE product_id = $product_id',
      { $amount: amount, $product_id: productId },
    ],
  ])
  return result
}

組み込みコンピューティング

しかし、私たちはさらに前進します。D1では、データベースの隣で直接実行されるWorkerコードの塊を定義することができ、完全な制御と最大のパフォーマンスをお届けします。各リクエストはまずお客様のユーザーの近くのWorkerに到達しますが、処理によっては、レプリカまたはプライマリのD1インスタンスと共にデプロイされた別のWorkerに引き継いで処理を完了させることができます。

バックアップと冗長性

メインアプリケーションのデータベースに保存されているデータほど重要なものはありません。そこでD1では、CloudflareのクラウドストレージサービスであるR2にデータベースのスナップショットを定期的に自動保存し、ワンクリックで復元できるようにしています。また、Durable Objectsの冗長化ストレージ上に構築されているため、データベースは必要に応じて物理的に場所を移動することができ、結果的に最も壊滅的な問題からも数秒で自己回復することができるのです。

データのインポートとエクスポート

D1は既にSQLite APIをサポートしているため、クエリを簡単に記述することができる一方で、クエリの実行にはデータが必要になる場合もあります。まったく新しいアプリケーションを作るのでなければ、他のソースやデータベースから既存のデータセットをインポートしたいと考えるでしょう。そのため、私たちはお客様自身のデータをD1に取り込めるように取り組んでいます。

同様に、SQLiteの利点の1つは移植性です。例えば、アプリケーションに専用のステージング環境があれば、そのデータのスナップショットをローカルマシンに複製し、それに基づいて開発を行うことができます。Pagesプロジェクトの新しいプルリクエストごとに、テストデータ一式と一緒に新しいデータベースを作成する機能など、より柔軟な機能を追加する予定です。

今後の展開は?

これは、「we’re just getting started!(まだ始まったばかりです)」で締めなければ、Cloudflareの発表とは言えません。- その通りです!私たちは、当社のグローバルネットワークにあるデータベースが切り開くパワフルな可能性にとても興奮しています。D1とWorkerを使用して何を作るか、もうお考えでしょうか?お客様について詳しくお聞かせください。できる限り早急にご連絡させていただきます。早ければ2022年6月からベータ版への招待状をお送りしますので、是非ご覧ください。