在计算机和软件世界艰难地向前发展的过程中,存在的一个不幸的事实,有时我们发现自己必须丢弃旧的数据。 我们从一个字处理 Office 程序包转移到另一个程序包,就发现旧的文档再也打不开了。
同样的情况也发生在数据库上。 一个小公司可能觉得将信息存储在一个 PC 数据库中就足够了,但在该迁移信息时将发生什么? 我们可能很苦恼要丢掉有价值的信息,但的确经常扔掉这些信息。 不过,当时可能看起来不是非常主要并被丢弃的信息,有时可能会需要。
我最近就碰到这样一个问题。 我工作的一个社区机构有一个基于 PC 的应用程序,它带有一个相当大的 Microsoft Access 格式的会员数据库。 已经编写了一个来自第三方的用户程序来与该数据库一起工作,但随后许可过期了,再没有方法来获取该软件的更新。 碰巧,忽然又非常需要这些信息。 我们备份了旧的数据库,并将之存储在一个 Linux 系统上。 在新的开放源代码世界中,为我们提供了许多强大的数据库(如 Linux 上的 Oracle 数据库)。 一种选择是购买一份 Microsoft Access 并创建一个应用程序,但这将把我们限制在同一个特定模型中,而这本来就已经使我们陷于困境。 此外,公司希望能够从一个安全的服务器远程访问这些数据。
再次依靠 Microsoft 不是我们希望的选择。 Linux 将作为这个新的数据库服务器的基础,并且它将运行一个行业标准的 SQL 数据库。 因此,假如我们着手取出限制在旧的 MDB 文件中的数据 — 而不依靠于安装带新的 Access 许可的 Windows 服务器(这样将再次受限于一个单体系结构解决方案),那将如何?
到处寻找解决困境的解决方案,我来到了 Brian Burns 的网站,并知道了他的 mdBTools 程序包,该程序包是命令行工具的一个集合还有一个 GUI,它的唯一的目的是提供从 Access 数据库中取出信息方法。
获取和安装 mdbtools
您需要做的第一件事是获取一份 mdbtools 程序包。 转至 http://mdbtools.sourceforge.net/,您将找到源代码和适用于几种基于 RPM 的版本的 RPM 程序包。 从源代码进行编译非常简单,包括提取到构建 5 个步骤。
tar -xzvf mdbtools-0.5.tar.gz
cd mdbtools-0.5
./configure
make
su -c "make install"
还可能通过下载和从 CVS 进行构建获得最新和最好的程序包。 这并不像它听起来那么复杂。 从连接并匿名登录 CVS 服务器开始。
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/mdbtools login
下一个步骤是查看 mdbtools 程序包:
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/mdbtools co mdbtools
注重前面的每一条命令都是完整的一行。 在输入上面的命令之后,当下载进行时,您将看到一个包含该版本中的各种文件的列表在屏幕上逐行显示。 当下载完成时,转移到下载目录(名称为 mdbtools)并执行以下命令。
./autogen.sh --enable-sql --with-unixodbc=/usr/local
make:
su -c "make install"
对 mdbtools 进行一些研究
mdbtools 程序包自带了一系列命令行工具以及一个 GUI,用于从 mdb 文件中处理和提取数据。 我将马上说明这个 GUI,但首先我想向您介绍一些命令行工具。 这些工具中最基础的是 mdb-ver,您可以用它来识别您要处理的 mdb 文件的类型。
$ mdb-ver members.mdb
JET3
这种情况下的结果是 "JET3",它告诉我我的社区会员文件是基于 Access 97 应用程序的。
返回值是 "JET4",则是 Access 2000 或 Access XP 数据库。 使用 mdb-tables 命令将开始出现稍微有趣一点的信息。
$ mdb-tables members.mdb
ActionTaken CaseMembers ContactFollowUp ContactReason ContactSource
ContactStatus Donations Issues Location MemberInfo PersonContacted Status ToDo
默认情况下,所有的数据库表将转储到一行上。 为了分别列出(每行一个表),可以使用 -1 标记。 不过,一些表不会显示;这些是系统表(以 Msys 开头的表)。 假如您希望这些表也列出来,那么可以使用 -S 标记。
上面的输出为您提供了组成您的 Access 数据库的各种表的具体分类。 有趣的是,我们实际上可以在数据库上执行 SQL 查询(尽管只能使用 SQL 的一个有限的子集),即使数据库不再在一个 Microsoft 系统上运行。 这就是 mdb-sql 命令的用途。 要进入交互式的 SQL 解释程序,可以输入 mdb-sql,后面紧跟数据库名称。 您将看到 1 = 提示符,您可以在提示符处输入单行或多行查询。 当您完成输入并且想运行查询时,输入 go,然后按 Enter 键。
$ mdb-sql members.mdb
1 = list tables
2 = go
在上面的例子中,我基本上重新创建了 mdb-tables 命令。 其不同之处是输出限定在美观的、带有标题并且四周用虚线框起来的表中。 当调用 mdb-sql 时,您可以重载这一行为,用 -H 来取消标题,用 -p 来去除边框。
$ mdb-sql -H -p members.mdb
您可以随时通过输入 quit 并按 Enter 键来退出 SQL 解释程序。
要创建一条查询,您可以使用默认的交互模式或在一行上发送一条查询。 在下面的例子中,我使用了另一条命令 — describe table 查询,该命令让我能够更深入地挖掘数据库的表的格式。
$ echo "describe table Location" mdb-sql members.mdb
+------------------------------+--------------------+----------+
Column Name TypeSize
+------------------------------+--------------------+----------+
IDLong Integer4
Address1Text255
Address2Text255
Address3Text255
Phone Text50
Fax Text50
DefaultIndBoolean 0
+------------------------------+--------------------+----------+
为了便于使用脚本,还可以用 -I 标记从外部文件中导入查询,以及用 -o 标记并指定一个文件名来将查询输出到一个文本文件中。
利用这些简单的 SQL 查询,我们能够了解到关于数据库的布局和其相关的表的许多信息。 通过加上边框的标题和美观的显示格式,我们可以导出到文本文件中,并利用 shell 脚本来处理结果。 实际上,假如您所需要只是您的旧数据的一些简单的报表,那么以上操作就足够了。 不过,假如您希望将数据库移植到一个基于服务器的 SQL 数据库(如 Oracle)中,那么 mdbtools 也可以在此为您提供帮助。 (当然,一旦您达到了这个目的您将如何处理数据就是一个完全不同的主题了。)
取出数据
取出数据至少有两个步骤。 第一步是在您的服务器上创建一个新的数据库和它相关的表。 第二步是加载数据。 利用上述示例,您可以获得关于组成原始的 Access 数据库的各种表的所有具体信息。 然后利用这些信息,您可以编写必需的脚本来专门为您的数据库逐个地重新创建这些表。 幸运的是,您不用太费力,因为 mdbtools 程序包也为此提供了一个工具。 它就是mdb-schema。 考虑到我的社区会员表包含了一些敏感信息,所以让我用 Microsoft Access 自带的练习数据库 Northwind.mdb 来进行演示。
$ mdb-schema Northwind.mdb
结果是模式的一个文本文件,该文件以 DDL(数据定义语言)格式发送至标准输出。 假如您想捕捉该输出(非常有用)则务必将该输出重定向到一个文件中。 DDL 输出默认是 Access 格式(如以下示例所示)。
DROP TABLE Customers;
CREATE TABLE Customers
(
CustomerIDText (10),
CompanyName Text (80),
ContactName Text (60),
ContactTitleText (60),
Address Text (120),
CityText (30),
RegionText (30),
PostalCodeText (20),
Country Text (30),
Phone Text (48),
Fax Text (48)
);
上面的输出只显示了一个表(为简洁起见),现在正好可以告诉您,您可以利用 -T 标记来指定单个表(我将马上演示这一操作)。
DDL 输出的数据库格式称为后端。 这时支持五个不同的后端。 它们是 "access" — 代表 Microsoft Access;"sybase" — 代表 Sybase;"oracle" — 代表 Oracle;和 "postgres" 代表 PostgreSQL(以及在 CVS 代码中的 "mysql" — 代表 MySQL)。 因此,要为 SavedQueries 表创建 Oracle 格式的 DDL,我使用下面的命令: