MySQL编程接口学习

之前有记下过关于MySQL的一些笔记《MySQL必知必会》摘录

以下是《MySQL技术内幕》的一些笔记,主要看第二部分:MySQL的编程接口 。


MySQL程序设计 


为什么要自己编写MySQL程序

那些标准的客户端程序足以解决MySQL用户日常遇到的绝大多数问题,但有些应用需求超出了它们的能力范围。为解决这类问题,MySQL服务器特意准备了一个客户

APIApplication Programming Interface,应用程序编程接口),我们可以利用该接口提供的灵活性满足应用程序可能会有的任何特殊要求。该客户端API的基本功能是访

MySQL服务器,它可以用来干什么就要看你的想象力了。

自行编写程序可以带来什么样的收获,下面把如此可以完成的事情与对mysql程序的能力及其提供的与MySQL服务器的简单接口的使用做个对比。

1.可以对输入处理环节进行定制。

在使用mysql程序的时候,只能输入原始的SQL语句;而在自行编写的程序里,可以向用户提供更直观和更容易使用的输入方法。只要编写的程序足够好,就可以让它的用户不

必掌握SQL语言,甚至觉察不出数据库在他们正在完成的任务里扮演的角色。数据输入界面可以简单到只有一个用来提示用户并读入数据的命令行接口,也可以复杂到是用某种

屏幕管理工具包(如cursesS-Lang)实现的全屏数据录入表单、用Tcl/Tk实现的一个X窗口、Web页面里的一个表单,等等。

对大多数人来说,通过填写一个表单的方式来给出搜索参数要比发出一条SELECT语句容易得多。比如说,一位正在根据价格范围、建筑形式或地点寻找房子的房地产经纪人,

肯定只想以最省事的法子把搜索参数输入一个表单并获得符合条件的房源清单。输入新数据行或更新现有数据行时也是如此:数据录入人员只需要知道在行内输入哪些值,而不

需要掌握INSERTREPLACEUPDATE等语句的SQL语法。

2.可以对用户提供的输入进行检查。

比如说,可以检查他们输入的日期是否符合MySQL所预期的格式,也可以要求必须填写某些字段。这可以提高应用程序的安全性。

3.可以自动生成输入数据。

有些应用可以根本不需要有人的参与,比如当MySQL需要的输入数据是由其他程序自动生成的时候。你也许会配置Web服务器把日志记录项写入一个MySQL数据库而不是一个文件,也许会设置定期运行的系统监控程序并且把系统状态信息写入一个数据库,等等。

4.可以对输出进行定制。

mysql程序的输出内容没有什么格式,只能选择使用制表符来分隔数据项或使用最简单的表格样式。如果想获得更美观的输出,就必须自己动手去排版它。这方面的要求可以简

单到只是把NULL值替换为“无”,也可以复杂到按规定生成一份报告。

5.可以克服SQL语言本身的某些先天不足。

绝大多数SQL脚本由一条条语句构成,它们将从头到尾依次执行,中间只进行最少的出错检查。如果用mysql程序的批处理模式去执行一个SQL查询文件,mysql程序要么会在遇

到第一个错误时退出,要么(如果你给出了--force选项的话)一口气执行完所有的查询面不管中间发生了多少个错误。如果是你自己编写的程序,就可以有选择地在查询命令的

前后加上一些流程控制语句,对其执行成功或是失败的情况做相应的处理。可以根据某个查询命令的成功或失败去执行另一个查询命令,也可以根据前一个查询命令的结果去决

定下一步该做什么。

6.可以把MySQL集成到任何应用程序里去。

有很多种程序会受益于数据库的信息提供能力,而MySQL客户端应用程序接口可以让它们获得这种能力。有了这种能力,当应用程序需要核对顾客号码或查看库存情况时,只

要发出一条查询命令即可;当Web应用程序收到某个客户查询某位作者所有作品的请求时,可以从一个数据库把它们检索出来并把检索结果发送回那个客户的浏览器。

应该承认,用mysql命令执行一个由SQL语句构成的输入文件,再用其他工具对其输出做进一步处理,这样利用shell脚本多少也可以获得一些把MySQL“集成”到应用程序里的

效果。但这种做法失于灵活,不适用于情况比较复杂的场合。如果一直采用这种“集成”方案,这种脚本会越来越多,其调试和补丁工作会越来越麻烦,到最后往往会陷入一

种“不用没办法,用起来很麻烦”的尴尬局面。不仅如此,利用shell脚本执行其他命令的做法在进程创建方面的开销很大,偶尔使用一次没什么,但长此以往恐怕就承受不起

了。更有效率的解决方案是让应用程序通过MySQL客户端接口直接与MySQL服务器交互,在其运行过程中的每一个阶段精确地提取出你所需要的信息。



MySQL应用程序可用的API

MySQL服务器有一个底层的“本地”客户/服务器协议,该协议对客户程序应该如何与MySQL服务器建立连接和通信做出了定义。客户可以在各种各样的抽象层使用这个协议。

1.为了支持应用程序的开发,MySQL提供了一个用C语言编写的客户端库,它使我们可以在任何一个C程序里去访问MySQL数据库。这个客户端库实现了一个API,该接口由一

组分别对应着各种本地协议操作的数据结构和函数构成。由这个库提供的C API比本地协议更便于使用。

2.MySQL与其他编程语言的接口可以把这个C客户端库链接到语言处理器里。利用这个客户端库提供的手段,我们就可以在C API的基础上实现MySQL与其他程序设计语言的接

口。PerlPHPPythonRubyC++Tcl等语言都有这种类型的接口。

3.MySQL与某些编程语言的接口采用了直接实现本地客户/服务器协议的办法来处理通信,没有使用C客户端库。JavaPHPRuby等语言都有这种类型的接口。


C API

C API用在经过编译的C程序上下文里。C API是一个客户端库,它提供了与MySQL服务器进行通信的接口,使我们能够与MySQL建立连接并进行通信。

MySQL发行版本里C客户程序都基于这个API。在MySQL与其他编程语言的接口当中,有相当一部分是以这个C客户端为基础的。比如说,正是因为链接了这个MySQL C客户端

库里的代码,与Perl DBI模块配套的MySQL驱动程序才能与MySQL服务器交互。


性能

如果其他方面都一样,我们当然更喜欢运行速度最快的应用程序。但在实际工作中,性能的重要性往往与程序的使用频率有关。对于一个每个月只在后半夜作为cron任务运行一

次应用程序来说,它的性能对全局几乎没有什么影响。但从另一个方面看,如果某个程序会在一个访问量极大的Web站点上每秒运行许多次的话,对其性能的一丁点儿改善都将

导致显著的差异。在后一种情况里,性能对网站的可用性和受欢迎程序有着巨大的影响。不管它提供的内容是什么,一个反应迟钝的网站肯定不会受到人们的欢迎。如果依赖这

样的网站作为收入来源,性能的低劣将直接转化为利润的减少。既然网站不能同时支持尽可能多的连接,就不要抱怨那些等得不耐烦的访问者会另寻他处了。

无论如何,至少有两个值得关注的基本因素会对性能产生相对持久的影响。

编译出来的程序要比以解释方式执行的脚本执行得更快。

对于用在Web上下文里的解释型语言,让解释器作为Web服务器的一个模块来运行要比作为另一个进程来运行的性能更好。


C语言编写MySQL程序 

编译和链接客户程序

利用MySQL C客户端库编写出来的程序要经过编译和链接才能执行。

在把源文件编译为目标文件时,要用-I选项把MySQL头文件的存放位置告诉编译器。比如说,要把源文件myclient.c编译为目标文件myclient.o,应该使用以下命令:

% gcc -c -I/usr/local/include/mysql myclient.c

在把目标文件链接到可执行代码时,要用-L/usr/local/lib/mysql-lmysqlclient参数把客户端库的存放位置和名称告诉给链接器,如下所示:

% gcc -o myclient myclient.o -L/usr/local/lib/mysql -lmysqlclient

如果客户程序由多个文件组成,就要在链接命令行上把所有的目标文件列举出来。

链接步骤经常会因“某函数没有定义”之类的错误而失败,此时,你需要增加一个-l选项把“某函数”所在的库的名字告诉给链接器。如果这类出错信息

compress()uncompress()函数有关,就要用-lz-lgz参数来告诉链接器zlib压缩工具库的位置:

% gcc -o myclient myclient.o -L/usr/local/lib/mysql -lmysqlclient -lz

如果这类出错信息与floor()函数有关,就要用-lm参数来链接数学函数库。也可能还需要增加其他函数库,例如,在Solaris系统上可能还需要-lsocket-lnsl参数。

你可以利用mysql_config工具程序来确定MySQL程序的编译和链接参数。比如说,这个工具程序可能会给出如下所示的输出:

% mysql_config --include

-I '/usr/local/mysql/include/mysql'

% mysql_config --libs

-L '/usr/local/mysql/lib/mysql' -lmysqlclient -lz -lcrypt -lnsl -lm

如果想把mysql_config直接用在编译或链接命令里,就需要把它放到一对反引号里:

% gcc -c 'mysql_config --include' myclient.c

% gcc -o myclient myclient.o 'mysql_config --libs'

系统将执行mysql_config并用执行结果替换反引号中的命令,自动地为gcc提供必要的编译或链接参数。

my_global.h文件。它负责把其他几个常用的头文件(如stdio.h)包括到源文件里。如果你正在Windows系统上编译这个程序,它还会把Windows兼容信息也包括进来。

my_sys.h文件。包含着为了提高代码的可移植性而定义的各种各样的宏,以及MySQL C客户端库所用到的各种结构和函数的定义。

mysql.h文件。它定义了基本的MySQL常数和数据结构。

文件的顺序非常重要:my_global.h应该在与MySQL有关的任何其他头文件之前被包括到源文件里。

1)调用mysql_init()函数获得一个连接处理程序。

2)调用mysql_real_connect()函数建立与服务器的连接。

MY_INIT()是一个初始化宏。它将把一个全局变量设置为指向你的程序名(你传给这个宏的参数值)供MySQL库在出错消息里使用。它还将调用my_init()函数来完成一些初始设置工作。

mysql_library_init()MySQL客户端库进行初始化。应该在调用任何其他mysql_xxx()函数之前调用它。

mysql_library_end()结束客户端库的使用并进行必要的清理工作。应该在用完客户端库之后调用它。

load_defaults()。负责读取选项文件。


出错检查

如果某个MySQL客户端库里的函数调用失败了,可以利用这个API里的3个函数来查找原因。

mysql_error()。返回一个包含出错信息的字符串。

mysql_errno()。返回一个MySQL专用的数值型出错代码。

mysql_sqlstate()。返回一个SQLSTATE代码。SQLSTATE值是在ANSI SQLODBC标准里定义的,与数据库软件的品牌无关。


处理SQL语句

我们连接MySQL服务器的目的是为了在连接打开时与它通信并交流信息。

最常用的语句发送例程是mysql_real_query()


更多可参考例程:

MYSQL C API 入门教程:http://www.cnblogs.com/sherlockhua/archive/2012/03/31/2426399.html


©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页