planetscale について
PlanetScaleでMySQL互換データベースを管理するためのスキルです。サーバーレスやエッジアプリを構築するチーム向けに、ブランチ、非ブロッキングなスキーマ変更、デプロイリクエストの手順を扱います。
主な機能
- 01データベースとブランチの作成・管理
- 02デプロイリクエストでスキーマ差分を確認
- 03接続認証情報の作成とブランチのプロキシ
- 04Prismaの設定とスキーマの反映
- 05Vitessのクエリインサイトを確認
活用シーン
- 01別ブランチでデータベーススキーマを開発
- 02本番スキーマ変更を確認してデプロイ
- 03ローカル開発用にPlanetScaleブランチをプロキシ
- 04サーバーレスアプリのコネクションプーリングを設定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill planetscaleインストール後、Claude Code で/planetscaleを入力して読み込まれたか確認します。
詳細
PlanetScale
Vitess を基盤とし、ブロッキングのないスキーマ変更ワークフローを備えた、サーバーレスの MySQL 互換データベースには PlanetScale を使用します。
使用する場面
- ダウンタイムなしのマイグレーションが可能な、マネージド MySQL 互換データベースが必要な場合。
- チームがスキーマ開発で Git のようなブランチ機能を使いたい場合。
- コネクションプーリングのメリットを活かせる、サーバーレスアプリケーションやエッジアプリケーションを構築する場合。
- Vitess を直接管理せずに水平シャーディングが必要な場合。
前提条件
- PlanetScale アカウント(無料プランあり)。
- ローカル環境に
pscaleCLI がインストールされていること。 - Prisma やその他の ORM との連携を使用する場合は Node.js 18 以降。
pscale CLI をインストールする
# macOS
brew install planetscale/tap/pscale
# Linux (deb)
curl -fsSL https://github.com/planetscale/cli/releases/latest/download/pscale_linux_amd64.deb -o pscale.deb
sudo dpkg -i pscale.deb
# Verify installation
pscale version
# Authenticate
pscale auth login
データベースを作成、管理する
# Create a new database
pscale database create my-app --region us-east
# List databases
pscale database list
# Show database info
pscale database show my-app
# Delete a database (destructive)
pscale database delete my-app
ブランチワークフロー
PlanetScale のブランチは、データベーススキーマにおいて Git のブランチのように機能します。デフォルトでは、main ブランチが本番ブランチです。
# Create a development branch from main
pscale branch create my-app add-users-table
# List all branches
pscale branch list my-app
# Open a shell on the branch to apply schema changes
pscale shell my-app add-users-table
ブランチにスキーマ変更を適用する
-- Inside the pscale shell on the development branch
CREATE TABLE users (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY idx_users_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE orders (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
total DECIMAL(10,2) NOT NULL DEFAULT 0.00,
status ENUM('pending','paid','shipped','cancelled') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
KEY idx_orders_user_id (user_id),
KEY idx_orders_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
PlanetScale はデータベースレベルで外部キーを適用しません。代わりに、アプリケーションレベルの制約または Vitess レベルのルーティングルールを使用してください。
デプロイリクエスト
デプロイリクエストは、データベーススキーマにおけるプルリクエストに相当するものです。差分を表示し、リンティングを実行してから、本番環境にブロッキングなしでマージします。
# Create a deploy request from branch to main
pscale deploy-request create my-app add-users-table
# List open deploy requests
pscale deploy-request list my-app
# Show diff for a deploy request
pscale deploy-request diff my-app 1
# Deploy (merge) the request
pscale deploy-request deploy my-app 1
# Close without deploying
pscale deploy-request close my-app 1
# Delete the branch after successful deploy
pscale branch delete my-app add-users-table
接続文字列とプロキシ
# Create a password (connection credential) for a branch
pscale password create my-app main production-creds
# Output includes host, username, and password for the connection string:
# mysql://USERNAME:PASSWORD@HOST/my-app?sslmode=verify_identity
# Proxy a branch to localhost for local development (no password needed)
pscale connect my-app add-users-table --port 3306
環境変数のパターン
# .env (local development using pscale connect)
DATABASE_URL="mysql://[email protected]:3306/my-app"
# .env.production (using PlanetScale connection string)
DATABASE_URL="mysql://USERNAME:[email protected]/my-app?sslaccept=strict"
Prisma との連携
// prisma/schema.prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // required — PlanetScale does not support foreign keys
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
orders Order[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Order {
id Int @id @default(autoincrement())
userId Int
total Decimal @db.Decimal(10, 2)
status String @default("pending")
user User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
@@index([userId])
@@index([status])
}
# Push schema changes to the PlanetScale branch
npx prisma db push
# Generate the Prisma client
npx prisma generate
Vitess の機能とクエリインサイト
# Open the query insights dashboard
pscale shell my-app main
# Inside the shell, check running queries
SHOW PROCESSLIST;
# Examine query statistics (PlanetScale Insights tab in the web UI)
# Or use the API:
pscale api organizations/my-org/databases/my-app/branches/main/query-statistics
Vitess を活用した便利なクエリ
-- Check table sizes
SELECT table_name,
ROUND(data_length / 1024 / 1024, 2) AS data_mb,
ROUND(index_length / 1024 / 1024, 2) AS index_mb,
table_rows
FROM information_schema.tables
WHERE table_schema = 'my-app'
ORDER BY data_length DESC;
-- Show index usage
SHOW INDEX FROM users;
-- Explain a query plan
EXPLAIN SELECT * FROM orders WHERE user_id = 42 AND status = 'paid';
ローカル開発用の Docker セットアップ
オフライン時や、CLI プロキシを使わずに迅速に反復開発したい場合は、通常の MySQL 8 コンテナを使用して PlanetScale のローカル環境を再現します。
# docker-compose.yml
version: "3.9"
services:
mysql:
image: mysql:8.0
restart: unless-stopped
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: my-app
MYSQL_USER: myapp
MYSQL_PASSWORD: secret
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
command: >
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
volumes:
mysql_data:
docker compose up -d
mysql -h 127.0.0.1 -u myapp -psecret my-app
本番環境のベストプラクティス
- すべてのスキーマ変更に後方互換性を持たせてください。先にスキーマをデプロイし、その後にアプリケーションコードをデプロイします。
- デプロイリクエストのレビューを必須にし、マージ前に少なくとも 1 件の承認を求めてください。
- サーバーレスのワークロードでは、コネクションプーリング(
@planetscale/databaseドライバーまたは Prisma Data Proxy)を有効にしてください。 - クエリインサイトを毎週確認し、実行に 100 ms を超えるクエリにはインデックスを追加してください。
mainへのデプロイを特定のチームメンバーのみに許可するよう、ブランチ昇格ルールを設定してください。- 読み取り専用リージョンを使用して、地理的に分散した読み取りのレイテンシーを低減してください。
トラブルシューティング
| 症状 | 考えられる原因 | 対処方法 |
|---|---|---|
pscale connect で Access denied が表示される | CLI が認証されていない | pscale auth login を実行します |
| デプロイリクエストに「schema conflict」と表示される | 同じテーブルに対するブランチ変更が同時に行われた | リベースします。ブランチを削除し、現在の main から作成し直して、変更を再適用します |
foreign key constraint エラーが発生する | PlanetScale は外部キーをサポートしていない | relationMode = "prisma" を使用するか、外部キー定義を削除します |
| 読み取り時のレイテンシーが高い | クエリ対象の列にインデックスがない | 新しいブランチでインデックスを追加し、デプロイリクエストを作成します |
max connections を超過した | コネクションプーリングが有効になっていない | @planetscale/database のサーバーレスドライバーまたは PgBouncer のようなプロキシを使用します |
pscale connect が応答しない | ファイアウォールが送信 TLS をブロックしている | *.psdb.cloud への送信ポート 443 を許可します |
関連スキル
- mysql - MySQL チューニングの基本
- database-backups - 復旧計画
- postgresql - 代替のリレーショナルデータベース
コメント
Markdown 対応