首页
技术库|站长工具|技术手册|字体库|知识点词汇表| 联系我们|
打开本页的html静态页面
 

主菜单

文章分类

.: PHP技术 .: PHP问题集锦 .: mysql_connect()与mysql_pconnect()有什么区别

  • 全文内容
  • 发表评论
  • 文章点评
  • 文章附件
  • Email文章
  • 打印文章

mysql_connect()与mysql_pconnect()有什么区别

点击次数:476 创建日期:10-20-2007 录入:cn-web.com 字体:[ ] 点评:


透过网页存取数据库内容的程序,多半要遵循以下几个步骤来进行:

  1. 建立数据库联机
  2. 选定欲存取的数据库
  3. 执行查询动作
  4. 取出查询结果
  5. 中断数据库联机

 以下将针对这几个步骤一一加以说明。


建立数据库联机

 我们将存取数据库的过程,想象成一艘货轮要进港载货。首先,港务局(MySQL)会对我们进行身分验证,以确定是否为货物的拥有者。在通过身分验证之后,我们将会得到一张「识别证」。

 一般而言,港务局会开放 3306 号港口(port)供我们上下货物,因此我们不必多费唇舌,可以直接驶入其中;否则,我们还要将货轮驶向特定的港口停放。

    $link = mysql_connect(HOSTNAME, USERNAME, PASSWORD);
    $link = mysql_connect(HOSTNAME:PORT, USERNAME, PASSWORD);

 上面这行叙述在对 MySQL 表明存取者的身分。其中的 HOSTNAME 是「主机名称」,若 Web server MySQL 同在一部机器上的话,可以写成「localhost」,否则请写数据库主机的名称或 IPUSERNAME PASSWORD 所指的就是要存取 MySQL 的账号密码了。

 一般的情况下,MySQL 会透过 3306 port 运作。若系统使用这项默认值的话,我们可以不用再加指定;否则请额外加入 PORT 参数来说明,如:「localhost:9000」。

 透过 mysql_connect( ) 的运作,MySQL 可以确认数据存取者的身分。成功的话,将回传一个「link identifier」;否则传回 FALSE


选定欲存取的数据库

 取得通行许可之后,接着进入货物区。这里可能会有许多间货品仓库(数据库),我们还要向管理员出示「识别证」,并从中挑选一间仓库。

    mysql_select_db(DBNAME);
    mysql_select_db(DBNAME, Identifier);

 上面的 DBNAME 指的是「数据库名称」,当面对单一数据库时,Identifier 可以省略不写。

 由于存取每个数据库都需要一个个别的 link identifier,所以若我们想同时存取两个数据库时,必须建立两个 link identifier ,并在 mysql_select_db( ) 里指明哪一个 link identifier 将对应到哪一个数据库。


执行查询动作

 此时,无论是要将货物搬上船,或是将船上的货品存放到仓库中,请将工作清单(QueryString)拿出来,然后就可以开工了。

    $result = mysql_query(QueryString);
    $result = mysql_query(QueryString, Identifier);
    $result = mysql_db_query(DBNAME, QueryString, Identifier);

 QueryString 即我们对数据库的查询动作,它可能是一段数据查询的叙述,也可能是新增、修改或删除等异动数据的要求。当 $result FALSE 时,表示这个存取动作是失败的;否则,它将会是一个编号(ID)。在「取出查询结果」的步骤,我们得靠它来识别这次的查询结果。

 在使用 mysql_query( ) 时,Identifier 是可以省略不写的。若我们不加以指定的话,系统会自动选用最近一次被使用的 link identifier

 如果我们先前「选定欲存取的数据库」这个步骤略过的话,现在可以改用 mysql_db_query( ) 来进行资料查询的动作。也就是说,mysql_db_query( ) 的功能等同于 mysql_select_db( ) 加上 mysql_query( )


取出查询结果

 取得货物以后,拆开来看吧!里头分装成一箱一箱的,我们可以算算有多少箱,也可以再把箱子拆开,取出里面的货品来。

 在上个步骤中,若我们执行的是查询动作的话,MySQL 会将结果包装成一个 result set,并传回它的编号(ID),接下来要读取数据时,都少不了它。

    $number_of_rows = mysql_num_rows($result);

 藉由 mysql_num_rows( ) 函数,我们可以得知这个 result set 里头有多少个数据列(row)。

 最后,再透过循环的运作,将 result set 里的每个资料列一一读出来。由于每个数据列可能含有多个字段,所以 $data 将会是一个数组;要一一显示个别字段内容的话,我们可以用 $data[0]$data[1]$data[2]...... 的方式。

    for ( $i=0; $i<$number_of_rows; $i++ ) {
        $data = mysql_fetch_row($result);
        echo $data[0];
        ......
    }

 要不然,使用以下这种方式也行:将各个字段的值存入相对应的变量中。

    for ( $i=0; $i<$number_of_rows; $i++ ) {
        list($value1, $value2, $value3, ......) = mysql_fetch_row($result);
        echo $value1;
        ......
    }


中断数据库联机

 任务达成,向港务局 say good bye 吧!

    mysql_close(Identifier);

 mysql_close( ) 可以用来关闭一个由 mysql_connect( ) 所建立的数据库连结,但是这个动作不是必要的。因为当一支程序执行结束之后,数据库连结会被自动中断。

 

经验谈

 在建立数据库联机时,除了上述的 mysql_connect( ) 以外,您也可以使用 mysql_pconnect( ) 来建立一个持续性的联机(persistent connection)。

 用 mysql_connect( ) 建立的联机,用完即丢,干净利落。不过,因为在建立数据库联机时,需要耗费一些时间与系统资源;若使用「持续联机」的话,同一部 web server 再向 MySQL server 请求联机时,可以直接使用先前用完闲置的联机,而不必重建。所以使用 mysql_pconnect( ) 来建立联机,可以节省时间,同时也能降低服务器的负担。

 两者相较之下,mysql_pconnect( ) 显然好得多,以后我们都使用它就好了。一般而言,这样的说法是对的,坊间的相关书籍几乎都支持这个论点;但我觉得它不完全正确,也就是说:在某些场合,mysql_pconnect( ) 是不适用的。


状况一:

 使用 1 web server 1 MySQL server(两者可能同在一部主机上),而 web server 固定只对 MySQL server 上的某一个数据库进行存取动作。

 因为每次存取数据库时,都是由 web 那边使用同一账号对 MySQL 上的同一数据库作业,若我们将 MySQL web server 的「同时联机数」都调整为 200,就好像 MySQL 这边一直有 200 位「服务生」,随时等着接待来自 web 200 位「顾客」似的。而且「顾客」离开之后,「服务生」也不下场休息,时时都站在门口等着接待下一个「顾客」。

 在这种情况下,您只要注意将 MySQL 的「同时联机数」调得比 web server 的高或相等,就会发现使用 mysql_pconnect( ) 是个不错的选择。


状况二:

 使用 1 web server 1 MySQL server(两者可能同在一部主机上),而 web server 会对 MySQL server 上的两个数据库进行存取动作。

 从 web server 那边提出数据存取需求时,有时是针对第 1 个数据库(DB1),有时则是针对第 2 个数据库(DB2)。若我们也将 MySQL web server 的「同时联机数」都调整为 200,这样一来,就好像 MySQL 这边有 200 位「服务生」,但同时经营两个「吧台」(DB1 DB2),而「顾客」可能多达 200 位。

 一开始,DB1 这个「吧台」比较热门,MySQL 派了 150 位「服务生」上场接待;同样地,当「顾客」离开之后,这 150 位「服务生」仍守着 DB1 而不下场休息。后来,DB2 那边也热闹起来了,「顾客」越来越多,MySQL 得加派「服务生」上场,有几个能派?答案是 50 个!

 为什么「服务生」的人力调配会捉襟见肘?那是因为 web 那边使用了 mysql_pconnect( ) 来建立联机。「服务生」一开始被指定到哪个「吧台」工作,就会持续在那边停留,绝不「转台」。


 请注意,当使用持续性的联机时,每个已建立的联机只为来自同一部 web server、使用同一组账号,且存取同一数据库的使用者服务。

 如此一来,假设每部 web server 的「同时联机数」都是 200,而且同时使用 2 web server 会怎么样呢?从 web1 来了 50 个「顾客」,先是到 DB1 走一趟,接着再到 DB2 晃一圈,这样需要多少「服务生」接待他们?100 个(web1->DB1: 50 web1->DB2: 50)!又从 web2 来了 50 个「顾客」,也做了同样的动作(web2->DB1: 50 web2->DB2: 50)。在此之后,还有「服务生」是闲着的吗?后续若从 web1 web2 同时涌入多于 50 位「顾客」时,谁来应付他们?

 倘若您使用的是像 Apache 这类的 multi-process web server(一个 parent process 协调一组 children processes 运作),某个 children process 建立的「持续联机」,是不能分享给其它 children process 来使用的(「服务生」只对先前接待过的「顾客」服务)。在这样的情况下,将会使得 MySQL 上闲置的 process 越积越多(很多「服务生」站在门口等着「老顾客」上门,而不理会「新顾客」)。

 mysql_pconnect( ) 一定是最佳选择吗?我想未必尽然。


说明:

 「同时联机数」是有上限的,当所有联机都被占用时,后续的联机要求就会被拒绝。「同时联机数」能调整到多高,这与服务器本身的效能是息息相关的,因为调得愈高,所消耗的系统资源也就愈多。


请文明参与讨论,禁止漫骂攻击。
评论总数:0 [ 查看全部 ] 网友评论
此文章还没有任何评论!
(+5分)
(+4分)
(+3分)
(+2分)
(+1分)
此内容无附件
网站地图 - 知识词汇 - 全文检索 - 广告服务 - 帮助中心 - 联系我们
.:www.cn-web.com
网站技术开发联盟之WEB开发技术知识库
联系人:老韩(QQ:5679551)
晋ICP备07003487号