yii2数据库迁移通过版本控制解决多人协作时的结构同步问题:需先配置db组件并连通数据库,用./yii migrate/create生成迁移文件(name仅限小写字母、数字、下划线),在up()中使用框架方法操作表结构,依赖关系须显式声明$depends,本地用./yii migrate同步,生产环境须指定版本执行。

团队多人开发时,数据库结构变更必须同步到每个成员本地环境,否则有人跑不通迁移、有人表字段缺失、有人数据错乱——这正是 Yii2 迁移版本控制要解决的核心问题。
生成迁移文件前的强制准备
进入项目根目录,确认 console/config/main.php 中已配置好 'db' 组件,且数据库可连通。若未配置,执行迁移命令会直接报错“Connection refused”,后续所有操作都卡死。
运行 ./yii migrate/create add_phone_to_user —— 注意 name 参数只能含小写字母、数字、下划线,不能带空格或大写,否则 Windows 下类加载失败(文件系统不敏感但 PHP 类名大小写敏感)。
生成的文件名形如 m260806_103522_add_phone_to_user.php,其中时间戳部分 【不可手动修改】,否则 Yii2 按字典序排序时会错乱执行顺序,导致依赖断裂。
迁移内容编写规范
打开新生成的迁移文件,在 up() 方法中写建表或改表逻辑,务必使用框架提供的方法而非裸 SQL:
✅ 正确:$this->addColumn('user', 'phone', $this->string()->null());
❌ 错误:$this->execute('ALTER TABLE user ADD phone VARCHAR(20) NULL'); —— 这种写法绕过 Yii2 的类型抽象层,跨数据库(如 PostgreSQL)直接失效,且无法被 down() 安全回退。
对已有字段做变更时,必须先判断字段是否存在,否则重复执行迁移会抛出 SQL 错误。例如添加索引前加检查:
if (!$this->db->getTableSchema('user')->getColumn('phone')) {<br> $this->addColumn('user', 'phone', $this->string()->null());<br>}
多人协作时的依赖声明
当你的迁移 A 依赖于他人已提交的迁移 B(比如先建了 user 表,你才给它加字段),必须在 A 的类中显式声明依赖:
第一步:找到迁移 B 的类名,例如 m260715_092211_create_user_table;
第二步:在迁移 A 的类定义顶部添加 public $depends = ['m260715_092211_create_user_table'];;
第三步:保存文件,再执行 ./yii migrate —— Yii2 会自动按依赖顺序执行,避免因执行时序错乱导致的 foreign key constraint failed 错误。
注意:Yii2 不按 Git 提交顺序执行迁移,只认文件名中的时间戳和 $depends 数组,靠“谁先 push 谁先执行”是危险幻觉。
本地同步与生产部署差异
方法一:本地开发同步
拉取最新代码后,直接运行 ./yii migrate。它会扫描 所有未执行过的迁移文件,按时间戳升序逐个执行,并在 migration 表中记录状态。
方法二:生产环境精确部署
严禁运行 ./yii migrate(默认跑全部未执行项)。必须指定版本:./yii migrate/up 3 或 ./yii migrate/to m260806_103522_add_phone_to_user。这样能确保只上线本次发布的变更,跳过中间测试用迁移,防止误删线上字段。
方法三:回滚仅限无业务数据场景
若刚在测试环境执行完迁移,且表为空,可用 ./yii migrate/down。一旦表里有真实用户数据,dropColumn 或 dropTable 就是不可逆操作 —— Yii2 不校验外键引用,也不提示字段是否被 Model 层硬编码调用。











