跳到主要内容

数据库迁移

问题

Rust 项目中如何管理数据库 Schema 变更?

答案

SQLx 迁移(推荐)

# 创建迁移
sqlx migrate add create_users

# 生成 migrations/20240115_create_users.sql
migrations/20240115_create_users.up.sql
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_users_email ON users(email);
// 应用启动时自动迁移
sqlx::migrate!("./migrations")
.run(&pool)
.await?;

Diesel 迁移

diesel migration generate create_users
migrations/20240115/up.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
email VARCHAR NOT NULL
);
migrations/20240115/down.sql
DROP TABLE users;

迁移最佳实践

原则说明
每次变更一个迁移文件不要修改已有迁移
提供回滚脚本便于紧急回退
向前兼容加列用 DEFAULT,改列分两步
版本控制迁移文件提交到 Git
零停机加列 → 代码兼容 → 改代码 → 删旧列

常见面试问题

Q1: 如何实现零停机数据库迁移?

答案

分步执行,保证每一步新旧代码都兼容:

  1. 加新列(允许 NULL 或有 DEFAULT)→ 部署
  2. 代码同时写新旧列 → 部署
  3. 回填数据 → 确认
  4. 代码只读新列 → 部署
  5. 删除旧列 → 部署

关键原则:每一步都要保证当前代码和上一版代码都能正常工作。

相关链接