Настройка PlanetScale для веб-приложения
PlanetScale — managed MySQL на базе Vitess (та же технология, что масштабирует YouTube и Slack). Главная особенность — branching для схемы базы данных: как git-ветки, но для структуры таблиц. Deploy requests позволяют делать schema changes без downtime и без страха заблокировать production.
Создание проекта
# Установка CLI
curl -fsSL https://raw.githubusercontent.com/planetscale/cli/main/install.sh | bash
# Аутентификация
pscale auth login
# Создание базы
pscale database create myapp --region eu-central
# Ветка по умолчанию — main (это production)
pscale branch list myapp
Подключение к production
# Прокси для локальной работы
pscale connect myapp main --port 3309
# Connection string
DATABASE_URL="mysql://[email protected]:3309/myapp"
Для production приложения — получить credentials в dashboard: Settings → Passwords → New password. PlanetScale не поддерживает прямые подключения без TLS.
DATABASE_URL="mysql://username:[email protected]/myapp?sslaccept=strict"
Branching для миграций
# Создать ветку для новой фичи
pscale branch create myapp add-user-profiles
# Подключиться к ветке
pscale connect myapp add-user-profiles --port 3309
# Применить миграцию к ветке
mysql -u root -h 127.0.0.1 -P 3309 myapp < migrations/add_profiles.sql
# Создать deploy request (как pull request для схемы)
pscale deploy-request create myapp add-user-profiles
# Посмотреть diff
pscale deploy-request diff myapp 1
# Задеплоить
pscale deploy-request deploy myapp 1
Prisma + PlanetScale
PlanetScale не поддерживает foreign keys на уровне базы (Vitess ограничение) — только application-level constraints.
// schema.prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // эмуляция FK на уровне Prisma
}
model User {
id String @id @default(cuid())
email String @unique
name String
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
}
model Post {
id String @id @default(cuid())
title String
content String? @db.Text
authorId String
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
@@index([authorId]) // обязательно при relationMode = "prisma"
}
# Создать миграцию (не применять к main напрямую)
prisma migrate diff \
--from-empty \
--to-schema-datamodel prisma/schema.prisma \
--script > migrations/0001_init.sql
# Применить к ветке
pscale connect myapp dev --port 3309
prisma db push # или вручную через mysql-client
Работа с данными
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient({
datasources: {
db: { url: process.env.DATABASE_URL }
},
log: process.env.NODE_ENV === 'development' ? ['query'] : ['error']
})
// Запрос с пагинацией
async function getPosts(page: number, limit = 20) {
const [posts, total] = await Promise.all([
prisma.post.findMany({
skip: (page - 1) * limit,
take: limit,
include: { author: { select: { id: true, name: true } } },
orderBy: { createdAt: 'desc' }
}),
prisma.post.count()
])
return { posts, total, pages: Math.ceil(total / limit) }
}
Insights — аналитика запросов
PlanetScale Dashboard → Insights показывает топ запросов по нагрузке. Не нужно настраивать slow query log вручную. Запросы без индексов выделяются отдельно.
Ограничения PlanetScale
- Нет поддержки хранимых процедур и триггеров
- Нет foreign key constraints на уровне БД
- Нет
SELECT ... FOR UPDATEв некоторых конфигурациях - Максимальный размер строки — 65535 байт
- Бесплатный план: 5 ГБ хранилища, 1 млрд row reads/месяц
Бэкапы
PlanetScale автоматически создаёт ежедневные бэкапы на платных планах. Ручной экспорт:
pscale database dump myapp main --output ./backup_$(date +%Y%m%d)
Сроки
Настройка PlanetScale проекта, подключение Prisma и настройка branching workflow: 1 день. Интеграция с CI/CD (автоматические deploy requests из ветки): ещё 1 день. Вся настройка с нуля для нового проекта — 1–2 дня.







