【发布时间】:2010-10-07 17:33:04
【问题描述】:
我正在开发一个使用本地 SQLite 数据库的 AIR 应用程序,并且想知道在分发应用程序的新版本时如何管理数据库架构更新。还考虑跳过某些版本的更新。例如。而不是从 1.0 到 1.1,而是从 1.0 到 1.5。
你会推荐什么技术?
【问题讨论】:
标签: database sqlite migration air
我正在开发一个使用本地 SQLite 数据库的 AIR 应用程序,并且想知道在分发应用程序的新版本时如何管理数据库架构更新。还考虑跳过某些版本的更新。例如。而不是从 1.0 到 1.1,而是从 1.0 到 1.5。
你会推荐什么技术?
【问题讨论】:
标签: database sqlite migration air
IMO 最简单的做法是处理来自例如的更新。 1.0 到 1.5 作为从 1.0 到 1.1、1.1 到 1.2 等的一系列更新。对于每个版本更改,保留一个转换脚本/一段代码。
然后,在数据库中保留一个带有版本字段的表,并将所需的版本编译到应用程序中。在启动时,如果版本字段与编译的版本不匹配,则一一运行所有需要的转换脚本。
理想情况下,转换脚本应该启动一个事务并将新版本写入数据库,作为提交事务之前的最后一条语句。
【讨论】:
我正在考虑将 SchemaVersion 表添加到数据库中,该表保存每个存在的版本的记录。 SchemaVersion 表的最后一个版本是数据库的当前级别。
我将创建 (SQL) 脚本来执行 1.0 的初始设置,然后从 1.0 升级到 1.1、从 1.1 升级到 1.2 等。
即使是全新安装,例如1.2 将运行所有这些脚本。这可能看起来有点慢,但只在(几乎)空数据库上完成一次。
这样做的一大优势是全新安装与升级安装具有相同的数据库架构。
正如我所说:我正在考虑这个。我可能会在明天开始实施。如果你有兴趣,我可以分享我的经验。我将为使用 LINQ-to-entities 与 SQL Server 和 MySQL 作为 DBMS 的 c# 应用程序实现此功能。
我很想听听其他人的建议和想法,如果有人能指出一个开源 .Net 库或实现类似功能的类,那就太好了。
编辑: 在对不同question here on SO 的回答中,我找到了对 Migrator.Net 的引用。我今天开始使用它,它看起来正是我想要的。
【讨论】:
我们为数据库的每个 DDL 更改编写脚本,当我们“发布”时,我们将它们连接成一个“升级”脚本,以及“自上次以来”更改的所有存储过程
我们有一个表格存储最新应用的补丁的版本号 - 因此升级工具可以应用任何更新的补丁。
每个存储过程都在一个单独的文件中。每个都以“插入”语句开始,该语句存储到存储 SProc 名称、版本和“现在”的日志表。 (实际上是执行一个 SProc 来存储这个,它不是原始的插入语句)。
有时在部署过程中,我们手动更改 SProc,或从 DEV 推出几率和结束,并比较客户端的 TEST 和 PRODUCTION 数据库上的日志,使我们能够检查所有内容是否处于同一版本。
我们还有一个“发布”主数据库,我们将更新应用到该数据库,并且我们使用该数据库的恢复备份进行新安装(节省了运行脚本的时间,这显然会随着时间的推移而增加)。我们会随时更新它,因为很明显,如果它有点陈旧,可以应用以后的补丁脚本。
我们的发布数据库还包含经过清理的启动数据(在新安装上线之前,这些数据已被删除,或者有时被采用和修改 - 因此它不包含在任何更新脚本中)
SQL Server 有一个工具栏按钮来编写更改脚本 - 因此您可以使用 GUI 工具进行所有更改,而不是保存它们,而是生成一个脚本。 (实际上,有一个复选框可以总是生成一个脚本,所以如果你忘记了,只需按 SAVE,它仍然会为你提供事后使用的脚本,可以将其保存为补丁文件)
【讨论】:
对于 SQLite,您可以使用 user_version pragma 来跟踪数据库的版本。获取版本:
PRAGMA user_version
设置版本:
PRAGMA user_version = 5
然后,我将每组更新保存在一个 SQL 文件中(嵌入在应用程序中)并运行所需的更新以升级到最新版本:
Select Case currentUserVersion
Case 1
// Upgrade to version 2
Case 2
// Upgrade to version 3
Case etc...
End Select
这允许应用将自身更新到最新版本,而不管数据库的当前版本如何。
【讨论】: