如何实现SQLite数据库自动升级?Oybab TradingSystem 版本1→16迁移脚本设计完全剖析

📅 2026/8/25 17:47:12
如何实现SQLite数据库自动升级?Oybab TradingSystem 版本1→16迁移脚本设计完全剖析
如何实现SQLite数据库自动升级Oybab TradingSystem 版本1→16迁移脚本设计完全剖析【免费下载链接】TradingSystemA multi-language cross-platform open source free software: Oybab Trading System.项目地址: https://gitcode.com/gh_mirrors/tr/TradingSystemOybab TradingSystem 是一款免费、跨平台的多语言收银交易系统它的 SQLite 数据库自动升级机制让程序每次启动时都能把旧版数据库平滑迁移到最新结构全程无需用户手动干预。本文带你读懂这套版本号 循环迁移的设计。为什么需要 SQLite 数据库自动升级这类收银系统的使用场景是店铺、餐厅、酒店数据文件就躺在服务器的硬盘上而软件会不断更新。一旦新版本要加字段、改表结构如果要求用户先导出、再重装、再导入对普通店主来说几乎不可能完成。Oybab TradingSystem 的做法是把升级逻辑写死在程序里服务启动时自动检测并执行。整个数据载体只有一个文件——ts.dbSQLite 单文件数据库升级时也不需要外部迁移工具。升级从哪触发启动加载时先读版本再干活入口在服务端加载缓存的 DBOperate.cs打开ts.db先只读一行数据——tb_database表对应模型 Database.cs把这一行交给升级器DBUpdate.Instance.UpdateDatabase(database)升级完成或本来就是最新版后才加载商品、会员、订单等全部业务缓存。tb_database表只有一行DatabaseId 1它是整个数据库的户口本关键字段有字段作用DatabaseVersion当前结构版本号如 16LastDatabaseVersion上一次升级前的版本号LastDatabaseUpdateTime上次结构变更时间UpdateTime本次升级时间戳yyyyMMddHHmmss也就是说程序不用猜这是哪一年的老库看一眼这张表就知道差多少级。核心设计while 循环 switch 脚本表所有升级逻辑集中在 DBUpdate.cs结构非常直白private int CurrentNewVersion 16; // 每次发新版改这里 while (oldVersion CurrentNewVersion) { switch (oldVersion) { case 5: sql SqlUpdateStatementVersion6; newNo 6; break; case 6: sql SqlUpdateStatementVersion7; newNo 7; break; // ... 逐级递进 ... case 15: sql SqlUpdateStatementVersion16; newNo 16; break; } // 执行 sql → 更新 tb_database 版本号 → 记操作日志 → 进入下一轮 }三个值得注意的工程细节逐级跳板而非一步到位从 5 升到 16 要跑 11 轮循环每轮只执行从 N 到 N1的那条脚本。这样任何中间版本的老库都能接上脚本之间互不依赖。死循环保险丝loopCount 99就抛出异常。这其实是一个隐性的设计约束——switch 里最小 case 是 5低于 5 的库不会命中任何脚本新库由CreateNewDB直接按最新结构创建正常不会遇到。每轮都留痕升级成功后写入操作日志Update To: N并在tb_database里记录LastDatabaseVersion事后可追溯这个库是什么时候从几升上来的。版本 1→16每一级脚本到底改了什么每条脚本是一个字符串常量SqlUpdateStatementVersionNSQLite 不支持ALTER ... DROP COLUMN等高级操作所以复杂改造都采用经典的改名旧表 → 建新表 → 拷贝数据 → 重建索引 → 删旧表五步套路。各级摘要级别主题关键变更5 → 6电子秤支持tb_product增加IsScales6 → 7进货多价体系进货明细加SalePrice/OriginalSalePrice/PriceMode7 → 8成本与卡号订单/外卖明细加TotalCostPrice会员/供应商加CardNo并建索引8 → 9开房计费包厢加FreeRoomPriceLimit订单加按时间计费、免房费开关9 → 10多付款方式重构重建会员/供应商付款表新增订单、外卖、进货、退货 4 张独立付款表10 → 11每一笔钱可追溯所有付款表统一加BalancePrice注释写着money is important need to track!11 → 12大扫除重命名全部外键约束为规范名重建十余张表清理冗余价格字段12 → 13支付与安全付款表加ParentBalancePrice管理员密码增加Salt盐值删除退货三张表13 → 14语言索引化名称类字段由ZH/UG/EN改为Name0/1/2编号模式语言可扩展14 → 15补丁级清理上一版可能残留的_tb_*_old_20200216旧表15 → 16钱箱支持tb_printer增加PrinterAddress与IsCashDrawer可以看出设计哲学版本号和功能发布一一对应每一级脚本短小、可独立回看出问题时能精确定位是哪一级脚本、哪张表。事务、外键与空间回收安全细节单条升级命令实际被包装成三段DBUpdate.csPRAGMA foreign_keysOFF; -- 迁移中临时放行外键避免拷贝旧数据时报约束错 本级迁移脚本 更新 tb_database 版本号 PRAGMA foreign_keysON;配套还有三层保险TransactionScope 事务整个脚本 版本号更新要么全成、要么全回滚不会出现表改了一半版本号却是新的的脏状态升级前自动备份DBOperate.cs 在加载前先调Backup.Instance.BackupFile()见 Backup.cs把ts.db压缩存档到备份目录升级翻车也有后悔药VACUUM 回收空间像 14 级这种重建全库的大手术升级完会追加一次vacuumIsCleanDB标志触发把改名删表留下的碎片页收走防止数据库文件只涨不缩。二次开发如何新增一个版本源码里的注释已经把发布清单写明白了DBUpdate.cs每次升级时要修改这里在底部的 switch 增加一个并在底部新增 SQL 脚本即三步①CurrentNewVersion加 1② switch 加一个 case③ 底部追加一条SqlUpdateStatementVersionN1字符串。由于是逐级跳板设计历史脚本永远保留、只增不改——这是整套机制能安全运行的前提。对普通用户意味着什么升级是透明的安装新版服务端后Windows 服务重启即自动完成数据库迁移通常只需几秒数据不会丢每级脚本都带数据拷贝且升级前有自动备份建议定期把备份目录指向第二块磁盘或 NAS老版本不能降级LastDatabaseVersion只记录来源、不提供反向脚本装回旧客户端读取新结构会有风险升级前记得确认备份可用。这套单行版本表 循环 switch 每级一个独立脚本 事务包裹 自动备份的组合是嵌入式/单机 SQLite 应用做数据库迁移最务实的模板之一值得任何需要维护单文件数据库的项目参考。【免费下载链接】TradingSystemA multi-language cross-platform open source free software: Oybab Trading System.项目地址: https://gitcode.com/gh_mirrors/tr/TradingSystem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考