跳转到内容

数据库迁移

StackRivet 里所有结构变更都走 Flyway。没有”手改生产库再补文档”这回事——迁移就是变更,进版本控制,启动时自动应用。

在所属模块内:

<module>/src/main/resources/db/migration/
common/ # 跨库通用的 SQL
mysql/ # MySQL 专属(方言差异)
postgresql/ # PostgreSQL 专属

可移植的语句放 common/;依赖方言特定语法的,拆进 mysql/postgresql/。StackRivet 支持 MySQL 8.4 LTS 和 PostgreSQL 18.4。

V<yyyyMMdd>_<seq>__<description>.sql
# 例如 V20260601_010__customer_management.sql

description ≤ 200 字符——过长会撑爆 Flyway 历史列、破坏 baseline。

表用 sr_ 前缀(模块表用 sr_<module>_<entity>),使 StackRivet 的表进入客户库后永不冲突。带上标准列:

CREATE TABLE sr_cm_customer (
id VARCHAR(32) NOT NULL,
tenant_id VARCHAR(32) NOT NULL DEFAULT 'default',
name VARCHAR(128) NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'active',
avatar_asset_id VARCHAR(32), -- 资产引用,绝不是 URL
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by VARCHAR(32),
updated_by VARCHAR(32),
deleted TINYINT NOT NULL DEFAULT 0,
deleted_at TIMESTAMP NULL,
version INT NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
CREATE INDEX idx_cm_customer_tenant_status ON sr_cm_customer (tenant_id, status);
CREATE INDEX idx_cm_customer_name ON sr_cm_customer (name);
为什么
idcreated_atupdated_at每张核心表必备
created_byupdated_by可审计表
tenant_id租户标识(默认 'default'
deleteddeleted_at软删除表
version乐观锁

对每个会用来过滤的列都加索引——代码生成器的索引风险检查会标出缺索引的查询字段。

应用启动时迁移自动运行(java -jar stackrivet-app/...mvn -pl stackrivet-app spring-boot:run)。启动后用健康检查确认:

Terminal window
curl http://127.0.0.1:8080/actuator/health # {"status":"UP"}

若启动报 Flyway checksum 不匹配baseline 漂移(通常是开发中一个半应用的迁移),清掉失败的历史行再重新迁移——仅限开发库

DELETE FROM flyway_schema_history WHERE success = 0;

然后重启应用。永远不要原地改一个已应用的迁移;新加一个。

可重复迁移(R__…)会在其 checksum 变化时重新应用。如果你改了一个,要么提交新 checksum,要么清掉失败历史行——别留 success = 0 的行,否则后面的迁移不会应用。