为了方便应用程序的开发,MySQL 提供了用 C 编程语言编写的客户机库,它允许从任何 C 程序的内部访问 MySQL 数据库。客户机库实现应用程序编程接口(API),API 定义客户机程序如何建立和执行与服务器的通信。
然而,使用 C 来编写 MySQL 程序并不受限制。许多其他语言处理器本身也是由 C 编写的,或具有使用 C 库的能力,所以 MySQL 客户机库提供了这个方法,由此, MySQL 对这些语言的约束可以建立在 C API 的上面。这就为与 MySQL 服务器通信而编写应用程序提供了许多选择。客户机程序的 API 是用 Perl、PHP、Java、Python、C++、Tcl 和其他一些语言编写的。
每种语言约束都定义自己的接口,特别是访问 MySQL 的规则。这里没有足够的时间来讨论 MySQL 可使用的每种 API,我们只讲述最流行的三种:
■ C 客户机库 API。这是 MySQL 的基本编程接口。
■ Perl 通用目标脚本语言的 DBI(数据库接口)API。DBI 是作为与其他模块在 DBD(数据库驱动程序)级接口的 Perl 模块来实现的,每个模块都提供对特定类型的数据库引擎的访问(当然,我们将讨论的特定的 DBD 模块也提供对 MySQL 的支持)。DBI 对 MySQL 的最普遍用法是编写由命令行来调用的独立的客户机,以及试图由 Web 服务器调用的脚本来提供 Web 对 MySQL 的访问。
■ PHP API。PHP 是一种脚本语言,它提供了在 Web 页中嵌入程序的一种便利的方法。在发送以前,这样的页面由 PHP 来处理,它允许这些脚本生成动态的内容,如在页面中包括 MySQL 查询的结果。“PHP” 原始的意思是个人主页( Personal Home Page),但是 PHP 的成长已经远远超过它简单的原始功能。PHP Web 站点现在使用的这个名称表示“PHP:超文本预处理程序( Hypertext Preprocessor)”,它像 GNU(是 GUN 而不是 UNIX )一样以同样的方式自我引用。
当标准的 MySQL 客户机不能满足需要时,您并不总是需要编写自己的程序。其他一些人一直编写程序,而这些程序中有许多是可共享得到的。只要找到几个就能节省您的许多工作。
以上这三种 API 都有专门章节详细说明。本章只提供对 API 比较的概述,用来说明它们的基本特征,并给出对特定的应用程序可能选择某个而不是其他 API 的原因。
当然,不必只考虑某个 API,应了解每个 API,并用可以明智选择适合自己的 API。在包括若干组件的大项目中,可能使用多个 API,多种语言,这取决于每个子任务适合哪一种语言。
CAPI 用于编译 C 程序上下文环境内部。它是一种客户机库,提供可用来与 MySQL 服务器对话的最低级别的接口----具有创建与服务器通信所需的能力。DBI 和 PHP 的前身 DBI 的 Perl 前身是 Mysqlperl 模块 Mysql.pm。这个模块不再被支持,而且不应该用于新的 MySQL 的开发。有一件事需要明白,Mysqlperl 是依赖于 MySQL 的,但DBI 不是。如果编写 MySQL 的 Perl 应用程序,然后,决定想用另外一种数据库引擎来使用它们,则移植 DBI 脚本比 Mysqlperl 脚本更容易一些,因为它们很少依赖于特定的数据库引擎。
如果获取了访问 MySQL 的一段 Perl 脚本,并发现它是用 Mysqlperl 而不是 DBI 编写的,则仍然可以使用 DBI。DBI 包括了对 Mysqlperl 的仿真支持,因此不需要安装两个程序包。PHP3 的前身是 PHP/FI 2.0 (FI代表“ form interpreter ,即格式解释程序”)。像 Mysqlperl 一样,PHP/FI 也是过时的,所以我们就不再进一步讨论它了。
MySQL C API 的起源如果已经有编写 mSQL RDBMS 程序的经验,那么将注意到 MySQLC API 类似于 mSQL 相应的 C API。当 MySQL 的开发者们开始实现他们的 SQL 引擎时,许多有用的共享实用程序可用于 mSQL。要想花费最小的难度将那些 mSQL 实用程序移植为 MySQL 的实用程序是可能的,可有意地将 MySQLAPI 设计为与mSQL API 类似(MySQL 甚至带有与 mSQL API 函数名称相应的 MySQL 名称的简单的文本替代品的msql2mysql 脚本。这个操作相对烦琐,实际上也照顾了许多涉及为使用 MySQL 而转换 mSQL 程序的工作)。
MySQL 分发包提供的C 客户机是基于这个 API 的。C 客户机库也作为 MySQL 对其他语言约束的基础来提供服务,但 Java API 是一个例外。例如,通过连接 MySQLC 客户机库代码,MySQL 可用 Perl DBI 模块专有的MySQL驱动程序和 PHP 代码。
Perl DBI APIDBI API 用于 Perl 脚本语言编写的应用程序的上下文环境内部。这种 API 在我们考虑的这三种 API 结构中是最高的,因为它可与许多数据库工作,而同时在脚本中可忽略许多特定数据库的细节。DBI 经过使用两级结构的 Perl 模块来实现。
■ DBI (数据库接口)级。为客户机脚本提供接口。这个级别提供的是抽象接口,并不是指特定数据库引擎。
■ DBD (数据库驱动器)级。在这个级别由特定引擎的驱动程序来提供对各种数据库引擎的支持。
MySQL 对 DBI 的支持环境由 Msql - Mysql - modules 分发包提供。这个模块在DBD 级操作。可以从分发包名称中分辨它,一个驱动程序可以提供对一个以上的RDBMS 的支持。Msql-Mysql-Modules 最初是为mSQL 而编写的,后来扩展到MySQL。这种影响类似于对 mSQL 和 MySQL 的 CAPI。由于设计的 MySQLCAPI 类似于 mSQL CAPI,所以将 mSQL DBD(使用 mSQL C API)扩展到对MySQL的使用很有意义。
DBI 体系结构编写应用程序的风格相对普通。当编写 DBI 脚本时,可使用一组标准的调用。DBI 级在 DBD 级调用适当的驱动程序来处理请求,对于想使用的特定数据库服务器通信中包括的特定问题,由驱动程序处理。DBD 级传送从服务器返回的数据,备份到 DBI 级,使数据出现在应用程序中。数据的格式与数据库的数据来源一致。
其结果得到这样一个接口,该接口从应用程序的编写者的观点隐藏了数据库引擎之间的差异,这样可使用多种不同的引擎----和驱动程序一样多。DBI 通过允许以统一风格访问每个数据库来提供一致性客户接口以增加可移植性。
当打开数据库时,出现由脚本编写的数据库专有的界面。当创建连接时,应指出使用哪个驱动程序。
连接以后,对该驱动程序不需要再做任何做特殊的引用。让 DBI 和该驱动程序解决数据库专有的细节。
无论如何这都是理论问题。然而,至少有两个因素与 DBI 脚本的可移植性矛盾:
■ 在RDBMS 引擎之间 SQL 的实现不同,为一个引擎编写的 SQL 另一个引擎根本不理解是完全可能的。如果 SQL 相当通用,则脚本可在引擎之间作相应的移植。但如果 SQL 依赖于引擎,则脚本也是这样。例如,如果使用 MySQL 指定的 SHOW TABLES 语句,则该脚本不能用其他数据库执行。
■ DBD 模块通常提供引擎专有类型的信息来允许脚本编写者使用特定数据库系统的特定功能。例如, MySQLDBD 提供访问查询结果中列属性的方法,如每列的最大长度、列是否是数值型的,等等。而这些属性在其他数据库中没有任何相似物。DBD 专有的特性与可移植性相背,通过使用它们,将 MySQL 编写的脚本用于其他数据库系统是困难的。
尽管存在数据库专有脚本的这两个因素,但以抽象方式提供数据库访问的 DBI 机制是完成可移植性的合理方式,只要您决定利用它多少次即可。
像 Perl 一样,PHP 也是一种脚本语言。但它与Perl 不同,PHP 很少作为通用目标语言来设计,而是作为编写 Web 应用程序的一种语言。PHP API 主要作为在 Web 页面中嵌入可执行脚本的一种方法来使用。这使Web 的开发者们很容易用动态生成上下文环境来编写页面。
当客户浏览器向 Web 服务器发送 PHP 页面的请求时,PHP 执行在该页面中它所发现的任何脚本,并用脚本的输出来替换它。该结果再送回浏览器。这就使浏览器中实际出现的页面根据请求的页面环境的不同而有所不同。例如,当在 Web 页面中嵌入下面简短的 PHP 脚本时,它出现所请求页面的主机 IP 地址:
可以使用脚本为访问者提供基于数据库上下文环境的最新信息。下面的样例说明可用于 Historical League Web 站点的一个简单脚本。该脚本发布一个请求来确定当前的 League 的成员数目,并将该数目报告给访问该站点的人(如果出现错误,则该脚本不报告任何数目):
尽管 DBI 级是独立于数据库的,而 DBD 级是依赖于数据库的,但那并不是“ DBI”和“DBD”所代表的意义。它们的意思是“数据库接口”和“数据库驱动程序”。
PHP 脚本通常看起来像是带有嵌入在“ ”标识符中的脚本的 HTML 页面。一个页面可能包括若干个脚本。这为脚本的开发提供了一种非常灵活的方法。例如,如果您喜欢,可以编写一个正常的 HTML 页面来创建通用的页面框架,然后再增加脚本的内容。
对于不同的数据库引擎,PHP 对统一的接口不再作任何事情, DBI 也用这种方法。取而代之,每个引擎的接口看起来非常像相应的实现该引擎低级 API 的 C 库接口。例如,用于从 PHP 脚本内部访问 MySQL 的PHP 函数的名称非常类似于 MySQL C 客户库中函数的名称。