数据库迁移
问题
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: 如何实现零停机数据库迁移?
答案:
分步执行,保证每一步新旧代码都兼容:
- 加新列(允许 NULL 或有 DEFAULT)→ 部署
- 代码同时写新旧列 → 部署
- 回填数据 → 确认
- 代码只读新列 → 部署
- 删除旧列 → 部署
关键原则:每一步都要保证当前代码和上一版代码都能正常工作。