便携式数据库管理系统 /rdb
Revolutionary Software 公司的 /rdb 数据库系统是一款紧凑、低成本的关系数据库管理系统,已在 Linux 和其他 Unix 变体上使用多年。它与大多数(如果不是全部)其他 Unix 数据库系统的区别在于,它作为 Unix shell 的扩展而运行。
典型的 Unix 发行版包含一组丰富的 shell 命令(通常称为 过滤器),例如 awk、grep 和 sed,它们主要对文本数据进行操作。此外,管道 可用于将一个命令的输出路由到另一个命令的输入。这些命令可以是上述标准命令,也可以是用户创建的命令。这种管道和过滤器系统通过重用已经过测试和验证的组件,简化了复杂应用程序的开发。
大多数过滤器设计为对 ASCII 文本数据进行操作,因此将逻辑数据记录表示为 ASCII 文本行是很自然的。记录中的数据元素由应用程序指定的字段分隔符字符(例如冒号或制表符)分隔。字母数字数据元素(如姓名、地址和描述)可以根据需要任意长或短。数字数据元素可以具有无限的大小和精度,并且它们的表示形式与体系结构无关。这种方案提供了平台之间数据的完全可移植性。
从其他平台继承而来的应用程序设计方法通常使用具有预定字段长度的固定长度字段。由于应用程序实际存储需求的不确定性,这些长度会导致文件空间浪费。数字数据通常以二进制格式存储,这使其高度依赖于平台且不可移植。诸如“描述”或“注释”字段之类的数据元素的大小可能差异很大,而使用固定长度字段迫使应用程序设计人员要么分配足够的存储空间来覆盖所有情况(通常是不可能的),要么为它们的存储分配单独的数据文件(通常使应用程序逻辑笨拙、复杂且难以管理)。
这些方法的结果是分配了永远不会使用的磁盘空间,以及难以维护的应用程序程序。尽管最近诸如 SQL 之类的创新简化了应用程序访问数据的问题,但许多程序仍与编译时确定的存储布局紧密绑定。每次需要更改记录格式时,代码与数据的这种绑定都会强制重新编译和重新链接应用程序代码。更糟糕的是,许多应用程序使用“填充字段”来避免重新编译,从而浪费更多的磁盘空间和 I/O 带宽。
虽然许多 Unix 系统(包括数据库系统)都使用上一节中概述的方法,但 /rdb 增强了标准 Unix shell 命令已提供的功能。许多 /rdb 命令充当标准 Unix 命令(如 awk)的前端。这使得已经熟悉 Unix 的用户无需学习新的编程语言即可创建 /rdb 应用程序。
/rdb 表格的格式非常简单。它们是 ASCII 文本文件,其中一行是一行数据。每行中的列元素由列分隔符字符(默认为制表符,但可以使用除换行符之外的任何其他字符)分隔。在列分隔符不是制表符的情况下,/rdb 命令使用 -f 命令行开关来指定列分隔符。请注意,这种方法与典型的 Unix 系统配置文件(如 /etc/passwd)之间的相似之处。唯一的区别是 /rdb 表格的第一行是分隔的字段名称集,第二行是一行破折号。前两行被称为表头。
/rdb 表格的美妙之处在于,对于某些应用程序,它们甚至不需要存储在磁盘文件中。相反,可以使用管道在命令之间传递它们。这些命令可以是 /rdb 命令或标准 Unix shell 命令。/rdb 命令设计为通过 stdout 输出表格,并且大多数接受通过 stdin 输入表格。尽管某些标准 Unix 命令会被表头行“混淆”,但 /rdb 提供了用于删除和重新附加这些表头的命令(分别为 headoff 和 headon)。
大多数 /rdb 命令都对通过 stdin 读取的表格进行操作。结果表格写入 stdout。以下是一些示例
row 'Cost < 50' inventory
选择库存表格中“成本”字段小于 50 的行。
column 'Description' < inventory读取库存表格并输出一个仅包含“描述”列的表格。
addcol 'Value' < inventory读取库存并输出一个新表格,该表格与库存相同,只是添加了一个名为“价值”的新列。此时,“价值”列中的所有字段都初始化为空字符串。
compute 'Value = Cost * Quantity'读取输入表格,并在每行上将“价值”设置为“成本”*“数量”。如果“价值”是列名,则计算值存储在表格中;否则,它仍然可以在同一计算语句中的其他语句中引用。
将这些命令放在一起,清单 1 中的 Bourne shell 脚本将输出一个表格,描述成本低于 50 美元的库存商品,并显示每件商品的价值。
这些命令只是 /rdb 提供的过滤器中的一小部分。有关完整列表,请参阅“资源”中列出的在线手册页。
行和计算过滤器实际上是 awk 的前端。由于 awk 不理解 /rdb 定义的字段名称,因此这些命令将字段名称转换为 awk 可以理解的列号。因此,熟悉 awk 的用户可以立即使用这些命令以及 /rdb 提供的许多其他命令。
由于 /rdb 表格是 ASCII 文件,因此可以使用任何文本编辑器创建和维护它们。这在许多情况下都有效,但在其他情况下会很麻烦,特别是对于宽表格或包含大量列的表格。/rdb 提供了两个表格编辑器,ve 和 jve,用于此目的。对这些编辑器的完整描述超出了本文的范围,但以下是所提供功能的部分列表
基于表单的数据输入: 可以使用 -s 选项指定屏幕文件(描述数据输入屏幕布局的 ASCII 文件),并用于将屏幕字段位置与表格列名称关联,并为某些字段提供初始化和写保护。
数据验证: -v 选项用于指定验证文件,以根据允许和不允许的字符范围、列长度限制、表格查找和基于命令的验证来提供数据编辑。使用基于命令的验证,可以将值传递给任何任意命令或 shell 脚本。退出状态向 jve 指示数据是否被认为是有效的(零表示成功,非零表示失败)。如果收到非零状态,jve 将发出蜂鸣声并在屏幕底部显示标准错误的第一行。
审计文件创建和维护: 审计文件跟踪对表格的更改,并且可以由 rollback 命令用于将表格恢复到特定时间点。
为了说明 /rdb 如何与其他 Unix shell 命令协同工作,清单 2 中的脚本显示了如何分析日志文件以报告服务器的前五个访问者。此脚本假定 stdin 是一个日志文件,其中包含以空格分隔的字段,主机名作为第一个字段(这对于 Apache 和其他几个 Web 服务器来说是典型的)。以下是该过程的逐步描述
awk 和 header 命令的组合生成一个表格,其中主机名按其在日志文件中出现的顺序排列。awk 的输出不是 /rdb 表格格式,因此使用 header 来完成表格的生成。
使用 addcol 命令,后跟 compute,添加一个名为 n 的列,并将其值初始化为 1。
然后按主机对表格进行排序,并使用主机作为控制中断来汇总 n 值,以生成主机名和每个主机的总访问计数(即 n 的值)的表格。
由于我们有兴趣查看访问计数最高的五个主机,因此按 n 对步骤 3 中生成的表格进行排序。
步骤 4 中表格的前七行(两行表头加上五行数据)被 head 命令过滤掉,并传递给 justify 命令,后者垂直对齐表头和列,并生成更适合打印的格式。
清单 2 中的脚本产生以下输出
host n wilbur.leba.net 106 gateway.amat.com 24 208.219.77.9 20 ras3.fsxnet.com 14 ohnp6.m50.nrc.ca 14
实际上,没有必要创建和存储任何 /rdb 表格。
现在我们来看一个稍微复杂的示例:邮件标签的生成。假设 stdin 是一个 /rdb 表格,其中包含名为 Salut(先生、夫人等)、Fname、Lname、Address1、Address2(有时为空白)、City、State 和 Zip 的字段,我们创建了 清单 3 中所示的脚本。
对于表格中的每一行,此脚本都会创建一个三行或四行的邮件标签(取决于是否使用了第二行地址)。在添加列以表示最终输出中的行之后,compute 命令确定它们的内容。结果表格按邮政编码排序,以便将标签分组以进行批量邮寄。 report 命令使用此处显示的 report.frm 文件格式化输出
<Line1> <Line2> <Line3> <Line4>
此文件是由 /rdb 用于生成报告的报表格式文件的一个非常简单的示例。方括号内的字段名称表示替换命名字段的内容。
还有其他报表文件选项可用,尽管我们在此处不作描述。最重要的选项之一是 shell 命令输出的放置位置。在此示例中,报表的输出是单列中的一系列标签。此数据通过管道传输到 pr,后者将其排列成两列。
/rdb 提供了五种访问方法:顺序(上述示例中使用)、记录、二进制、倒排 和 哈希。提供了一个 index 命令来构建索引文件,并提供了一个 search 命令来执行键检索。
为需要通过 C 程序访问的用户提供了一组库函数 librdb.a。还包括这些函数的完整 C 源代码。
/rdb 是一款功能强大但低成本的软件包,适用于各种数据库管理任务。它具有以下优点
低成本:Linux、SCO 和其他 Intel Unix 实现仅需 149 美元,RISC 平台需 495 美元。
学习曲线短:已经熟悉 Unix 的用户可以快速掌握。
硬件要求低:/rdb 安装仅需不到 5MB 的磁盘空间。/rdb 命令很紧凑,因为它们主要充当标准 Unix 工具的前端。上面介绍的邮件列表应用程序是一个“真实世界”的程序,以前是使用 dBase 文件完成的。由于 dBase 文件使用固定长度字段,因此它们包含大量尾随空格,这些空格在转换为 /rdb 表格时被消除。因此,/rdb 表格大约是原始 dBase 文件大小的三分之一。
与其他 Unix 命令良好集成:Web 服务器日志分析示例说明了这一点。人们可以轻松地为其他系统(包括其他数据库)创建通用接口程序,并使用 /rdb 在输入端提供数据输入和验证,并在输出端提供报表生成。
数据和代码的可移植性:随着网络计算环境变得越来越普遍,这一点变得越来越重要。
唯一的缺点是,与特定于机器的系统相比,独立于平台的系统通常运行速度较慢。此外,可变长度记录往往比固定长度记录更难管理。即便如此,/rdb 即使对于大型数据库也能表现良好(有关 Web 上提供的演示指针,请参阅“资源”)。即使在可能需要更传统的数据库系统的极端情况下,/rdb 仍然可以用作前端,如清单 2 所示。
最后,硬件独立性与性能权衡所涉及的经济考虑因素是显而易见的。硬件性价比正在迅速下降,而程序员的时间成本却在不断上升。在这种情况下,硬件独立性是无可争议的赢家。
