4

我正在研究使用 ORM(反对关系映射器)来允许我将 C++ 对象持久保存到 SQLite 数据库中。我目前正在考虑 CodeSynthesis 的 ODB。

见: http: //www.codesynthesis.com/products/odb/

查看 ODB 的文档,我没有看到我的一个烦人的问题的答案,即:

如果我创建一个类,将其保存到数据库,但随后在我的产品的更高版本中更改该类,会发生什么情况。当用户获得我的软件的新版本时,如何将旧数据正确加载到新版本的类中?

我之前看过 boost::serialize ,它有处理这种“升级”的机制,但我想知道:

  1. 一般来说,这在 ORM 工具中是如何处理的?
  2. 如何专门用 ODB 做到这一点
  3. 有没有比 ODB 更好的 ORM 工具来处理这个问题?
4

2 回答 2

7

从一开始,充分披露:我在 ODB 工作。并回答你的第三个问题,不,没有;-)。

不过说真的,模式演化是一个难题,它是我们 TODO 列表中的三大项目之一(另外两个是多数据库支持和 SQL-to-C++ 编译器)。好消息是我们已经完成了多数据库支持,下一个是模式演变。

通常,最好的方法似乎是将您的架构(以及数据,如果需要)更新到最新版本。使应用程序能够读取多个不同版本的替代方案似乎在现实世界中无法扩展。

例如,假设我们向类中添加了一个数据成员,该成员在数据库模式级别转换为向相应表中添加一列。处理这个问题的方法是使这个新列可以为 NULL(例如,odb::nullable 或 boost::optional)。这里的想法是,该列没有值的旧数据将为 NULL(应用程序可以检测和处理)。

接下来我们需要升级数据库中的模式。在这种情况下,我们需要执行 ALTER TABLE ADD COLUMN 语句来添加新列。一旦 ODB 支持模式演化,它将自动生成这些迁移语句。现在你必须自己写它们(我知道这很痛苦)。表中的所有现有行都将自动为该列分配 NULL 值。

所以通常一个应用程序将包含一组这样的语句,这些语句将模式从一个版本升级到下一个版本。例如,从 1 到 2,从 2 到 3 等。数据库将存储模式版本,应用程序将知道其最新的模式版本。打开数据库后,应用程序将立即检查数据库版本,如果它低于应用程序架构版本,它将开始运行这些迁移集以将架构升级到最新版本。

于 2012-11-30T15:50:09.187 回答
0

如果您仍然对 ODB 的替代方案持开放态度,您可能会考虑 quince:http: //quince-lib.com(并完全披露:我写的)。

关于升级数据类型的具体问题:quince 不会自动检测进化的需要,或设计进化策略或类似的东西。它为您提供的是 ALTER TABLE 的 C++ 接口。但积极的一面是:这都是在 C++ 级别:您根据 C++ 数据类型来描述您的更改,并且所有这些都经过静态类型检查。

于 2014-07-14T06:41:27.353 回答