PlanetScaleというサーバレスDBが凄く勢いのあるサービスらしいのでQuick Startやってみた

PlanetScaleというサーバレスDBが凄く勢いのあるサービスと聞いて、公式にクイックスタートがあったのでやってみました。

# 環境
- PC: MacBook Pro (Intel Core 2016)
- OS: macOS Montery12.2.1

では概要から確認していきます。

# サーバーレスDBとは
- サーバがない、のではなく、サーバ管理や検討が不要
- AWS Lambda(NoSQL)など

# PlanetScaleとは

https://planetscale.com/

![Screen Shot 2022-02-25 at 23.34.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/1ff3bc73-05d1-ad84-6825-8835ba19cfa7.png)

# PlanetScale年表
- 2010年頃
  - YouTubeが急激に成長し、データベースが爆発しそうになっていたので、Sugu氏ともう一人のYouTubeのエンジニアがオープンソースプロジェクト「Vitess.io」（ヴィテス）を立ち上げる
- 2016年頃
  - MySQLでバイナリプロトコルを扱えるようにしたことで、VitessはYouTube以外の企業にとっても魅力的なシステムになり、引き合いが来るようになる
- 2018年頃
  - Vitessの開発者Sugu Sougoumarane氏と、YouTubeのDBAマネージャーとしてVitessに関わったJitendra Vaidya氏が共同で設立
- 2021年7月19日
  - 元GitHubのエンジニアリング担当副社長Sam Lambert（サム・ランバート）氏がCEOに就任
  - https://planetscale.com/blog/new-ceo-of-planetscale
- 2021年11月
  - 総額1億500万ドル（約120億円）を調達

非常に勢いがありそうなのはなんとなく伝わります。

# 何を解決しようとしているのか
とある記事を見つけたので抜粋いたします。

PlanetScaleは、サーバーレスの現代において、クラウドベースのデータベースの単純性とパフォーマンスとスケーラビリティのバーを高くしました。データベースのデベロッパー体験は、あまりにも長く苦痛を感じるものでした。PlanetScaleは、その鎖を切ろうとしています。スケーラビリティと信頼性における長年の問題を、同社は極めてエレガントで趣味が良く便利な方法で解決しています。

出典元)https://jp.techcrunch.com/2021/06/24/2021-06-23-planetscale-raises-30m-series-b-for-its-database-service/

# サービス概要
- MySQL8を速くて簡単にスケーラブルに利用できるサービス
- YouTubeやSlackなどでも利用されているVitess（ヴィテス）というMySQLの水平スケーリングシステムを利用しており、ノンブロッキングでスキーマ変更できる
- ブランチ機能があり、GitのようにDBを管理できる
  - https://docs.planetscale.com/concepts/branching
- SQLはダッシュボード上か、CLI上で動かせてすぐ確認ができる
- TablePlusなどのDBを確認できるツールと連携も可能
- Rails / Laravel / Node.js / Prisma 向けのチュートリアルも充実している
- 自動でバックアップも取る
- 2022/02/25現在、日本語のソースはほとんどなさそう

:::note info
水平スケーリングは、負荷の増減に合わせてサーバーの数を増やしたり（スケールアウト）減らしたり（スケールイン）する方法。クラウドと相性が良いアプローチだといえる。
:::

:::note info
ノンブロッキングとは、随時処理の確認と複数の処理を並行する処理。
:::

ブランチ機能は面白そうだなと思いました。

# 利用事例
- YouTube
- Slack
- Figma
- GitHub
- Square
- New Relic
- MyFitnessPal
- Affirm
- その他...

![Screen Shot 2022-02-25 at 23.41.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/48ecb3ed-c783-ac8d-7248-7fe3f2d6474d.png)

# 利用料金
- 無料枠
  - ストレージ > 10GB
  - 読み込み > 1億回
  - 書き込み > 1000万回
  - コネクション > 1000
  - ブランチ > 3つ
  - 自動バックアップ > あり
  - オートスケーリング > なし
- $29/月
  - ストレージ > 250GB
  - 読み込み > 5億回
  - 書き込み > 5000万回
  - コネクション > 10000
  - ブランチ > 10
  - 自動バックアップ > あり
  - オートスケーリング > あり
- 以降は、$29/月の利用枠を超過した分だけ課金

https://planetscale.com/pricing

個人で試してみるには無料枠でも十分そうです。

# 登録からDB作成まで
![Screen Shot 2022-02-25 at 23.44.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/be4c5c4e-2339-3069-1258-5dd2e548217f.png)

TOPページから「Sign in」をクリックすると、このような画面にくるので、
今回は「GitHub」と連携させてみます。

「GitHub」をクリックします。

![Screen Shot 2022-02-25 at 23.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/73f7db66-fe61-56f8-7ffe-4c7d1b6683b0.png)

> 利用規約を更新しました。更新された利用規約をお読みになり、同意してください。

と書かれているので「`Accept Terms of Service`」をクリックします。

![Screen Shot 2022-02-25 at 23.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/824ca519-abc1-6712-5434-c9f6df1c33c8.png)

すると、

> GitHubに登録してあるメールアドレスへ承認メールを送ったよ

と言われるのでメールを確認します。

![Screen Shot 2022-02-25 at 23.47.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/64c0df46-8d4d-4784-6472-4ade31cb4219.png)

メールを確認すると、画像のようなメールが届いており、
> アカウントの作成を完了するために、Eメールを確認してください。

と記載されているので、
「`Confirm email`」をクリックします。

すると、以下のような画面に飛びます。

![Screen Shot 2022-02-25 at 23.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/2cbe34e3-ceff-fbb4-52fb-77961fd54e47.png)

**hogehogeというあなたのための組織を作りました。別の名前を使いたいですか？**
と聞かれているので、別の名前を使う場合は、「`use a different name`」をクリックします。

今回はそのままで良いので、「`See how PlanetScale works`」をクリックしました。

ここからはPlanetScaleについて色々**解説**が始まります。
一応1つ1つ見てみます。

![Screen Shot 2022-02-25 at 23.50.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/8c84baa6-1837-8371-2dc5-dda702875fff.png)

> サーバーレスデータベース
MySQLの信頼性とオープンソースVitessのスケールを備えたフルマネージドデータベースを、わずか10秒で導入できます。内蔵のコネクションプーリングは、データベースへの接続制限に陥ることがないことを意味します。

![Screen Shot 2022-02-25 at 23.54.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/03f2a839-02af-bc88-2aef-5db7546e56e1.png)

> PlanetScale独自のデータブランチ機能
データベースをコードのように扱う。本番データベースを即座にブランチして、スキーマの変更をテストするためのステージング環境を作成します。

![Screen Shot 2022-02-25 at 23.55.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/527fbbf9-3730-c60c-29a5-7eda7cc64085.png)

> ノンブロッキングスキーマの変更
PlanetScaleのノンブロッキングスキーマ変更機能により、スキーマ変更を本番環境に安全にデプロイすることができます。CI/CDプロセスの一部としてスキーマ管理を簡単に自動化できます。

![Screen Shot 2022-02-25 at 23.56.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/3503f119-0d4b-1eec-ea16-b494784e15eb.png)

> デプロイリクエスト
デプロイリクエストは、スキーマの変更を提案し、チームからフィードバックを得ることができます。一行ごとのスキーマ差分により、変更点を簡単に確認することができます。
デプロイリクエストと GitHub プルリクエストをペアにして、コードとスキーマの変更を並行してレビューすることができます。

![Screen Shot 2022-02-25 at 23.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/04ad8f5e-0206-0bf7-e7af-e3dea2721204.png)

> スキーマの変更をデプロイする
スキーマの変更が承認されると、デプロイメントキューに追加されます。PlanetScale はデプロイメントのタイムラインを提供し、キューに入れられたスキーマ変更がどれも衝突しないようにします。

![Screen Shot 2022-02-25 at 23.58.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/623ee538-92d8-4d32-ce90-ef3038c56d1d.png)

> インサイトとモニタリング
データベースの読み取りと書き込みを追跡するグラフで、本番環境のトラフィックを把握することができます。クエリ統計機能により、遅いクエリを特定し、最適化することができます。
データベースを作成し、PlanetScale ワークフローを開始します。

解説はここまでです。

「`Create your first database`」をクリックします。

# DB名とRegionを決める
DB作成のモーダルが表示されるので、Regionを「Asia Pacific Tokyo」にして、
Nameを任意のDB名にします。

![Screen Shot 2022-02-25 at 23.59.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/82ea4506-fc06-8228-675d-5c2c1015f1e5.png)

DB名は、**小文字の英数字でダッシュまたはアンダースコアを使用することもできます。**

![Screen Shot 2022-02-26 at 0.01.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/530e3652-26d9-1171-1742-6783ce4480bc.png)

今回は「my-database」というDB名にしました。

これで、「`Create Database`」をクリックします。

![Screen Shot 2022-02-26 at 0.01.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/1891e72f-f403-eee3-0d6a-7d8b8ec8f13e.png)

しばらく待っているとDBが作成されてこのような画面になります。

上部のタブメニューは左から「概要 / リクエストのデプロイ / ブランチズ / 統計のクエリ / 設定」となっています。

画面左側は、「過去6時間」の状況が確認できます。
過去どこまで遡るかは、プルダウンで選択できます。

画面右側は、「テーブル / ブランチ数 / 接続数」が確認できます。

その下には、「毎月の使用量は7日間でリセットされます。プランのアップグレードで制限解除」
と記載されています。

さらにその下には、「次のバックアップは19時間後に実行されます。まだバックアップは実行されていません。」と記載されています。

## Backupされている時の表示
![Screen Shot 2022-02-26 at 0.03.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/829cc8c0-3c7d-3625-3be5-f83bade1da43.png)

Backupされていると、いつバックアップされたかが表示されます。

# Quick Startやっていく
ここからは公式ドキュメントに「Quick Start」があったのでやっていきます。

https://docs.planetscale.com/tutorials/planetscale-quick-start-guide

## とりあえずクエリを叩いてみる
まずは、ダッシュボードからクエリを叩いてみましょうということで、
タブメニューの「Branches」から「main」をクリックします。

![Screen Shot 2022-02-26 at 0.05.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/21a93aca-a34d-43e0-0304-0af9d0055662.png)

すると、次の画面になります。

![Screen Shot 2022-02-26 at 0.07.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/b2388991-7c0d-2d6e-8c77-0e3cc03a06be.png)

> このデータベースには本番ブランチないけど、ブランチを本番環境に昇格させますか

というようなことが書かれているのですが一旦無視をして「`Console`」タブをクリックします。

## テーブルの作成
すると、mainブランチに対して接続中という状態でコンソールが表示されますので、
クイックスタートに書かれている通りのクエリを入力してEnterを押してみます。

![Screen Shot 2022-02-26 at 0.06.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/bc26f05c-5bad-67d8-94e1-62046be3b0c0.png)

```sql
CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `email` varchar(255) NOT NULL,
  `first_name` varchar(255),
  `last_name` varchar(255)
);
```

続いては、テーブルが作成されたか確認します。

```sql
show tables;
```

![Screen Shot 2022-02-26 at 0.08.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/784e1021-dd0f-760d-eb60-24ce0e3cee85.png)

無事テーブルが作成されました。

## データの投入(INSERT)
テーブルが作成されたので、次はインサートしていきます。

![Screen Shot 2022-02-26 at 0.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/8fd298bc-19d3-220a-bd2d-3a7c38456180.png)

```sql
INSERT INTO `users` (id, email, first_name, last_name)
VALUES  (1, 'hp@test.com', 'Harry', 'Potter');

SELECT * FROM users;

DESCRIBE users;
```

無事にハリーポッターがインサートされました。

## mainブランチを本番用にして保護する
mainブランチを本番用にして、**誤って削除などができないように保護**します。
PlanetScaleではブランチを本番用にすることで、CREATEやDELETEなどができないように保護されます。

![Screen Shot 2022-02-26 at 0.11.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/7add1945-a09d-6376-2d5c-750ceb141900.png)

タブメニューの「`Overview`」をクリックして、mainブランチであることを確認したら、
「`Promote a branch to production`」をクリックします。

すると、以下の画像のようなモーダルが出ますので、
「`Promote branch`」をクリックします。

![Screen Shot 2022-02-26 at 0.13.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/1cda2d67-8e90-2b1a-69ea-6d1a1fd52259.png)

ここでは、以下の文言が書かれています。

> 本番用ブランチには、開発用ブランチと比較して、さらに多くのメリットがあります。
・スキーマの直接変更から保護される
・高い可用性
・自動定期バックアップ
この操作は元に戻すことができません。
管理者のみがプロダクションブランチを削除することができます。

## 新しい開発用ブランチを作成する
mainブランチが本番用に切り替わると、以下の画像のような画面になります。

![Screen Shot 2022-02-26 at 0.14.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/cadbed80-9079-7687-430e-49d4a56aeab9.png)

画面真ん中には「mainはプロダクションブランチです」と書かれています。

その下は左から

> プロダクションブランチとは何ですか？
本番用ブランチは、可用性が高いブランチです。削除は組織管理者のみ可能で、スキーマの変更はデプロイリクエストを経由する必要があります。

> 接続方法を教えてください。
上の接続メニューから、本番環境のアプリケーションをこのブランチに接続してください。

> アップデートはどのように行うのですか？
mainブランチでスキーマを変更し、デプロイリクエストを発行してください。

と書かれています。

まずは、開発用のブランチを作りたいので「`Create new branch`」をクリックします。

ブランチ作成のモーダルが以下のように表示されますので、
今回は「**develop**」という名前で新規作成します。

![Screen Shot 2022-02-26 at 0.16.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/3de73d99-3111-ed53-d706-fb5a6d2481e3.png)

Gitと同じように **Base branch** が選択できます。

入力内容に問題がなければ「`Create branch`」をクリックします。

無事作成されると以下のようになります。

![Screen Shot 2022-02-26 at 0.18.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/a0c1ade6-e08d-3aee-5699-29bc007ee69b.png)

## DBに接続
続いては、DBに接続してみます。

先程の画面右上の「`Connect`」をクリックします。

![Screen Shot 2022-02-26 at 0.19.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/18a1ccc0-e8a9-457c-bea0-cc0a6d645ec0.png)

すると、以下のようなモーダルが表示されます。

![Screen Shot 2022-02-26 at 0.20.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/0b3b8a6c-9ac0-3105-10c0-9380293cf318.png)

記載されている内容は以下の通りです。

> 以下は、このデータベースに接続するための詳細です。より詳細な情報が必要な場合は、ドキュメントを参照するか、サポートに連絡してください。

> データベース認証の認証情報
初期作成後のパスワードは表示できません。

> pscale CLI を使用して、ターミナルからデータベースを管理し、接続します。

今回、PlanetScale CLIを使うためインストールします。

## PlanetScale CLIのインストール

https://github.com/planetscale/cli#installation

今回はhomebrewで入れます。

```bash
brew install planetscale/tap/pscale
```

### エラーが出た
インストール時に以下のようなエラーになりました。

```none:原文
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

If that doesn't show you any updates, run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 13.2.1.
```

```none:翻訳
エラーが発生しました。コマンドラインツールが古すぎます。
システム環境設定のソフトウェア・アップデートから更新するか、以下を実行してください。
  softwareupdate --all --install --force

これでアップデートが表示されない場合は、実行してください。
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

または、手動で以下からダウンロードしてください。
  https://developer.apple.com/download/all/。
Xcode 13.2.1用のコマンドラインツールをダウンロードする必要があります。
```

なので、 `softwareupdate --all --install --force` を実行します。
終わったら、もう一度 `brew install planetscale/tap/pscale` を実行します。

私の環境下ではそれでもエラーが解消されなかったので、以下を実行して完了までしばらく待ちます。

```bash
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
```

みたび `brew install planetscale/tap/pscale` を実行します。

やっとインストールできたので、念のため `pscale --version` で確認します。

```bash
pscale --version
```

すると以下のように表示されました。
```bash
pscale version 0.89.0 (build date: 2022-01-24T18:17:47Z commit: 6405542)
```

無事インストールされていましたので、次のコマンドを叩きます。

```bash
pscale auth login
```

```
もしくは、
pscale signup
pscale signupの時はConnectをクリックした時の情報をターミナルで入力が必要
```

`pscale auth login` を叩くと、ブラウザ側で以下のサイトが開きます。

![Screen Shot 2022-02-26 at 0.30.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/bab11d8a-744d-6e53-e174-c5f0aaa8ba89.png)

「`Confirm code`」をクリックします。

するとターミナル側で `Successfully logged in.` と表示されており、
これだけでログインが完了します。

## CLIで接続確認
ログインが完了したら、先に接続確認をしてみます。

ターミナルで以下のコマンドを実行します。

```bash
pscale shell <DB_name> <Branch_name>

今回例： pscale shell my-database develop
```

接続ができたら以下のようになります。

![Screen Shot 2022-02-26 at 0.37.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/8a7a6207-9c2b-0926-3315-cd5367f70392.png)

`<DB_name>/<Branch_name>` のように表示されていると思います。

インストール時に、もしMySQLがないと言わられたらインストールしましょう。

```bash
brew install mysql-client
```

### 再度データの投入をしておく
先ほど、 **mainブランチ** から新しく **developブランチ** を作成しましたが、**データの中身は別** だったので、再度データを投入しておきます。

```sql
use users;

INSERT INTO `users` (id, email, first_name, last_name) VALUES  (1, 'hp@example.com', 'Harry', 'Potter');

select * from users;

exit
```

## サンプルのNode.jsでDBへ接続する
続いては、サンプルのNode.jsからDBへ接続してみます。

以下のドキュメントを確認します。

https://docs.planetscale.com/tutorials/connect-nodejs-app#set-up-the-starter-nodejs-app

GitHubからサンプルを取得することになるので取得します。

```bash
git clone https://github.com/planetscale/express-example.git
```

express-sampleフォルダが取得できるので、依存関係をインストールします。

```bash
npm install
```

以下のコマンドで接続を試みます。

```bash
pscale connect <DATABASE_NAME> <BRANCH_NAME> --execute 'node app.js'

今回例： pscale connect my-database develop --execute 'node app.js'
```

ちなみに、サンプルのapp.jsの中身は以下のような感じです。

```javascript
require('dotenv').config();
const express = require('express')
const app = express()
const port = process.env.PORT || 3000

const mysql = require('mysql2')
const connection = mysql.createConnection(process.env.DATABASE_URL);

connection.connect()

app.get('/', (req, res) => {
  connection.query('SELECT * FROM users', function (err, rows, fields) {
    if (err) throw err

    res.send(rows)
  })
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})
```

localhost:3000/ が立ち上がりますので、http://localhost:3000/ を開きます。

すると、先ほどインサートしたデータが表示されます。

![Screen Shot 2022-02-26 at 0.46.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399610/27421b17-6398-eeaf-fef5-9127daaed54f.png)

## .envファイルを作成してから接続する方法
先ほどのコマンドからではなく、.envで環境変数を用意してからの接続方法もあります。

`mv .env.example .env` で .env ファイルを作成して、中身を書き換えます。

```
"mysql://<USERNAME>:<PLAIN TEXT PASSWORD>@<ACCESS HOST URL>/<your-db-name>?ssl=true"

pscale password create <DATABASE_NAME> <BRANCH_NAME> <PASSWORD_NAME>
```

詳細は公式ドキュメントをご確認下さい。

https://docs.planetscale.com/tutorials/connect-nodejs-app#using-a-connection-string

# まとめ(感想)
- 個人で試すには無料枠でも十分なので試しやすい
- ブラウザのダッシュボード上での操作やCLIから色々できたり使いやすそう
- 自動バックアップは嬉しい
- ブランチ機能ちゃんと理解して使うと良さそう

# 文献一覧
- https://docs.planetscale.com/
- https://docs.planetscale.com/tutorials/planetscale-quick-start-guide
- https://www.publickey1.jp/blog/18/serverless.html
- https://zenn.dev/nbr41to/scraps/94e502af17e9fd
- https://techblitz.com/planetscale/
- https://jp.techcrunch.com/2021/12/27/2021-11-16-planetscale-raises-50m-series-c-as-its-enterprise-database-service-hits-general-availability/
- https://xtech.nikkei.com/atcl/learning/lecture/19/00043/00001/?P=2
- https://it-trend.jp/development_tools/article/32-0037