数据迁移实战:建表与版本升级时容易忽略的5个致命细节

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
插件开发 27 浏览 0 回复

最近在重构一个老插件时踩了不少坑,总结下数据迁移中最容易翻车的几个场景。建表SQL看着简单,但版本迭代时经常出现字段漏改、索引失效等问题:

1. 默认值陷阱 ALTER TABLE时如果没显式声明NOT NULL,老数据会被自动填充NULL而不是默认值:

// 错误示范
ALTER TABLE `plugin_orders` ADD COLUMN `payment_type` TINYINT DEFAULT 1;

// 正确姿势
ALTER TABLE `plugin_orders` ADD COLUMN `payment_type` TINYINT NOT NULL DEFAULT 1;

2. 索引重建暗坑 修改字段类型时原索引不会自动重建,必须显式DROP INDEX:

ALTER TABLE `plugin_logs` 
 CHANGE COLUMN `create_time` `create_time` INT(11) NOT NULL,
 DROP INDEX `idx_time`,
 ADD INDEX `idx_time` (`create_time`);

3. 卸载残留问题 卸载插件时记得清理自定义数据库表,但要注意保留用户数据的需求场景。建议采用标记删除模式:

// 卸载脚本示例
if (!defined('IN_UNINSTALL')) {
    $db->query("DROP TABLE IF EXISTS `plugin_temp_data`");
    $db->query("UPDATE `user_meta` SET `is_deleted`=1 WHERE `meta_key`='plugin_settings'");
}

4. 版本回滚预案 在upgrade.php中一定要写版本回退逻辑,特别是涉及数据迁移时:

// 版本210→220升级失败时回滚
if ($failed) {
    $db->query("ALTER TABLE `plugin_items` DROP COLUMN `new_field`");
    return false;
}

5. 字符集连环炸 跨版本迁移时遇到过最恶心的就是utf8mb4冲突,一定要在建表时显式声明:

CREATE TABLE `plugin_comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

评论0
回复 · 0
还没有回复
微信客服 微信客服