数据库迁移痛点
在开发一个应用的过程中,数据库 schema 经常需要修改 - 添加表、字段、索引等。这将导致开发、测试和生产环境的数据库 schema 不同,给开发和部署带来困难。
为了解决这个问题,我们需要一种管理数据库变更的机制,这就是数据库迁移。
目标是:
- 跟踪数据库的变更
- 可以进行前进和回滚迁移
- 使开发、测试和生产环境的数据库保持一致
Flyway简介
Flyway 是一款开源的数据库迁移工具。它可以管理SQL脚本来演进数据库schema,并将开发、测试和生产环境的数据保持同步。
Flyway的主要特征是:
- 可以将SQL脚本和数据库绑定在一起(通过文件名),这样就可以准确的检测到数据库的当前状态
- 支持前进迁移和回滚迁移
- 具有"语义版本控制" - 通过文件名确定迁移脚本的顺序
- 支持SQL和Java两种迁移脚本
- 可以在CI/CD管道中集成,保证开发、测试和生产环境的一致性
使用Flyway进行数据库迁移
这里以一个简单的例子来说明如何使用Flyway进行数据库迁移:
- 添加Flyway依赖。以Maven为例:
<dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>6.5.3</version>
</dependency>
- 创建迁移脚本。文件名遵循V{版本号}__{描述}.sql的格式。例如:
V1__Create_user_table.sql
V2__Add_email_column.sql
- 在程序中配置Flyway
Flyway flyway = Flyway.configure() .dataSource("jdbc:mysql://localhost/mydatabase", "username", "password").locations("classpath:db/migration") // 迁移脚本目录.encoding("UTF-8") // 编码.schemas("my_schema") // schema名字.table("schema_version") // 元数据表名.baselineOnMigrate(true) // 第一次运行时创建baseline.validateOnMigrate(false) // 迁移时不校验SQL.load();
flyway.migrate(); // 执行迁移
- 执行迁移
调用 flyway.migrate() 时,Flyway 会执行所有未执行的迁移脚本,将数据库更新到最新版本。
在第一次运行时,会创建一个 schema_version 表,用来保存迁移的元数据信息。 - 其他操作
Flyway 还提供了许多其他 API :
- flyway.baseline() : establishing a new baseline for a database derby
- flyway.repair() : 修复损坏的迁移
- flyway.clean() : 在迁移前清理数据库
- flyway.info() : 打印迁移信息
- flyway.undo() : 执行回滚迁移
springboot中如何使用
在 Spring Boot 中使用 Flyway 也很简单。我们只需要添加 flyway 的 starter依赖,并在 application.properties 文件中配置 Flyway 即可。
- 添加依赖
<dependency><groupId>org.flywaydb</groupId><artifactId>flyway-spring-boot-starter</artifactId><version>6.5.3</version>
</dependency>
- 配置 Flyway
在 application.properties 中添加:
spring.flyway.url=jdbc:mysql://localhost/mydatabase
spring.flyway.user=username
spring.flyway.password=password
spring.flyway.locations=classpath:db/migration # 迁移脚本目录
- 编写迁移脚本
迁移脚本名称同上,放在 classpath:db/migration 目录下。 - 启动应用
当 Spring Boot 应用启动时,Flyway 会自动执行所有未执行的迁移脚本,将数据库更新到最新版本。
同时,Flyway 也会在应用启动阶段执行初始化或修复操作。我们可以在配置文件中指定:
spring.flyway.baseline-on-migrate=true # 第一次启动时创建baseline
spring.flyway.repair=true # 启动时检查并修复损坏的迁移
spring.flyway.clean-on-validation-error=true # 校验 SQL 错误时,自动清理并重试
这样,Spring Boot 应用的数据库就能够在应用第一次启动时自动 initializing 到最新版本,并在之后保持同步。这大大简化了我们在不同环境之间维持一致数据库 schema 的难度。
在开发过程中,数据库schema 的变更也变得更加容易和流畅。我们只需要添加新迁移脚本,重启 Spring Boot 应用,Flyway 就会自动执行迁移将数据库更新到最新版本。