业务经理

微信扫描以上二维码

028-61286886

技术咨询

1. 为什么要迁移

  • 安装与运行时 DDL 需同时跑在 MySQLiSQLite3 上。

  • 裸 SQL 里的 ENGINEAUTO_INCREMENTSHOW CREATE TABLETRUNCATE、索引前缀 col(191) 等在 SQLite 上会失败或语义错误。

  • 统一走 \Phpcmf\Service::M('table'),由驱动做方言转换,业务侧只写 MySQL 风格的字段定义字符串即可。

调用约定:业务优先 \Phpcmf\Service::M('table') / M();表是否存在用 is_table_exists / is_field_exists;建表用 install_schema / create_table;删表用 drop_table;清空用 clear_all;导出结构优先 create_table_sql() / create_table_schema()

2. 对照总表

旧写法新写法
Config/Install.sqlCREATE TABLE ...Config/Install.php 调用 install_schema([...]);保留空的 Install.sql 占位
Config/Uninstall.sqlDROP TABLE ...Config/Uninstall.php 调用 drop_table(...);保留空的 Uninstall.sql 占位
INSERT 种子数据写在 Install.sqlinstall_schemaseeds,或 Install_data.sql(仅 DML)
ALTER TABLE ... ADD COLUMNM('table')->add_field($table, $name, $type, $info, $note)
ALTER TABLE ... MODIFY / CHANGEedit_field;改名可「加新列 → 拷数据 → 删旧列」
ALTER TABLE ... DROP COLUMNdrop_field($table, $name)
DROP TABLE ...drop_table($物理表名, true)
TRUNCATE TABLE ...M()->table($逻辑表)->clear_all()
SHOW CREATE TABLEcreate_table_sql($table)create_table_schema($table)
CREATE INDEX ... / ALTER ... ADD INDEXadd_index($table, $name, $columns);建表时放在 schema 的 indexes
手写批量 DDL 字符串尽量改 schema;若必须拼串,经 dr_format_create_sql() / Table::_query

3. 安装:Install.sql → Install.php

3.1 文件约定

  • 逻辑放在 Config/Install.php(框架在装应用时 require)。

  • 不要删除 Install.sql / Install_site.sql,改为空白占位文件(空文件经 query_all 会安全跳过)。

  • 仅 DML 的种子可继续放 Install_data.sql(无 CREATE/ALTER)。

3.2 旧写法示例

3.3 新写法示例

tables 的键是逻辑表名(不含前缀)。install_schema 内部会 dbprefix($name)create_table。            字段定义仍用 MySQL 方言字符串;SQLite 驱动会在建表时自动转换。

4. 卸载:Uninstall.sql → Uninstall.php

旧 · Uninstall.sql

新 · Uninstall.php

同样保留空的 Uninstall.sql / Uninstall_site.sql 占位文件。

5. 运行时 DDL

5.1 判断表 / 字段是否存在

5.2 建单表

5.3 增删改字段

5.4 清空表

\Phpcmf\Service::M()
    ->table('xxx')
    ->clear_all();

5.5 加索引

\Phpcmf\Service::M('table')->add_index(
    \Phpcmf\Service::M()->dbprefix('xxx'),
    'uid_status',
    ['uid', 'status']   // 或 'uid,status'
);

6. 结构导出与克隆

需求API说明
拿到 CREATE 文本 + 字段片段create_table_sql($table)返回 [$create, $fieldsMap, $table];勿再 SHOW CREATE TABLE
导出可再安装的 schemacreate_table_schema($table)得到 fields / indexes / comment,可写入 Content.php / Form.php

备份/导出工具若要把 DDL 写进文本文件,可用 create_table_sql 得到的字符串;运行时建表仍应走 schema / create_table

7. Table 门面 API(常用)

类:Phpcmf\Model\Table,调用:\Phpcmf\Service::M('table')

方法作用
install_schema($schema)按 tables + seeds 安装
create_table($table, $fields, $indexs, $note)创建单表
drop_table($table, $ifExists = true)删除表
add_field / edit_field / drop_field字段级变更
add_index($table, $name, $columns)创建索引
create_table_sql / create_table_schema结构读取 / 导出
create_field($table, $config)按字段类配置批量加列(内部仍可能经字段类 create_sql

底层实现位于驱动:

  • dayrui/System/Database/MySQLi/Connection.php

  • dayrui/System/Database/SQLite3/Connection.php

若仍有批量旧 SQL 字符串需要执行,经 Table::_query / dr_format_create_sql(),由驱动 formatCreateSql 转换后再执行。

8. 字段 / 索引书写约定

  • 字段定义:继续写 MySQL 风格,如 'varchar(255) NOT NULL COMMENT \'标题\'''int(10) unsigned NOT NULL AUTO_INCREMENT'

  • 索引行:使用 PRIMARY KEY (`id`)KEY `name` (`name`)UNIQUE KEY `uk` (`a`,`b`)

  • 不要写索引前缀长度:如 (`text`(191))。SQLite 会把 text(191) 当成函数调用,报 no such function: text / ip 等。需要前缀时由 MySQL 侧自行优化,schema 里写完整列名即可。

  • 表名:schema 键用逻辑名;传给 create_table / drop_table / add_field 时一般传已加前缀的物理名(dbprefix(...))。

  • decimal(10,2) 等类型括号是字段类型的一部分,不要和索引前缀混淆;解析时需按括号深度切分。

9. 可暂留与不要改的范围

范围说明
字段类 create_sql() 返回的 ALTER框架约定路径,可暂留;最终由驱动/门面消化
空的 Install.sql / Uninstall.sql必须保留占位,不要删除
备份/导出拼出的 DDL 文本作为导出内容可含 CREATE 字符串;运行时执行勿直接裸跑 MySQL 专用语法
注释掉的历史分表 DDL可不迁;新逻辑用 schema
Dever 代码生成模板 Code/*.sql模板用途,按生成器能力再改
Zhuanhuan* 等迁移工具明确不改

10. 迁移检查清单

  1. 搜索应用内:CREATE TABLEALTER TABLEDROP TABLETRUNCATESHOW CREATE

  2. 把安装 DDL 挪到 Install.phpinstall_schema;卸载挪到 Uninstall.phpdrop_table

  3. 把对应 .sql 清成空文件(不要删文件)。

  4. 运行时变更改为 add_field / edit_field / drop_field / create_table / clear_all / add_index

  5. 去掉索引列上的 (数字) 前缀长度。

  6. 在 MySQLi 与 SQLite3 各装一遍插件,确认建表、加字段、卸载正常。

  7. 若曾用「数据转换」迁过库,转换逻辑升级后建议重新转换,避免旧索引定义残留。

本文地址:https://www.xunruicms.com/doc/xunrui/1492.html