- ·上一篇文章:用PHP+MySQL搭建聊天室
- ·下一篇文章:用PHP控制您的浏览器cache
五个常见 PHP 数据库问题
ks(
idMEDIUMINTNOTNULLAUTO_INCREMENT,
author_idMEDIUMINTNOTNULL,
nameTEXTNOTNULL,
PRIMARYKEY(id)
);
INSERTINTOauthorsVALUES(null,'JackHerrington');
INSERTINTOauthorsVALUES(null,'DaveThomas');
INSERTINTObooksVALUES(null,1,'CodeGenerationinAction');
INSERTINTObooksVALUES(null,1,'PodcastingHacks');
INSERTINTObooksVALUES(null,1,'PHPHacks');
INSERTINTObooksVALUES(null,2,'PragmaticProgrammer');
INSERTINTObooksVALUES(null,2,'Rubyalign=centerbgColor=#e7e9e9border=1> <?php
require_once('DB.php');
$dsn='mysql://root:password@localhost/good_books';
$db=&DB::Connect($dsn,array());
if(PEAR::isError($db)){die($db->getMessage());}
functionget_author_id($name)
{
global$db;
$res=$db->query("SELECTidFROMauthorsWHEREname=?",array($name));
$id=null;
while($res->fetchInto($row)){$id=$row[0];}
return$id;
}
functionget_books($id)
{
global$db;
$res=$db->query("SELECTidFROMbooksWHEREauthor_id=?",array($id));
$ids=array();
while($res->fetchInto($row)){$ids[]=$row[0];}
return$ids;
}
functionget_book($id)
{
global$db;
$res=$db->query("SELECT*FROMbooksWHEREid=?",array($id));
while($res->fetchInto($row)){return$row;}
returnnull;
}
$author_id=get_author_id('JackHerrington');
$books=get_books($author_id);
foreach($booksas$book_id){
$book=get_book($book_id);
var_dump($book);
}
?>
如果您看看下面的代码,您可能会想,“嘿,这才是真正的清楚明了。”首先,得到作者id,然后得到书籍列表,然后得到有关每本书的信息。的确,它很清楚明了,但是其高效吗?回答是否定的。看看只是检索JackHerrington的书籍时要执行多少次查询。一次获得id,另一次获得书籍列表,然后每本书执行一次查询。三本书要执行五次查询!
解决方案是用一个函数来执行大量的查询,如下所示。
清单16.Get_good.php
<?php
require_once('DB.php');
$dsn='mysql://root:password@localhost/good_books';
$db=&DB::Connect($dsn,array());
if(PEAR::isError($db)){die($db->getMessage());}
functionget_books($name)
{
global$db;
$res=$db->query("SELECTbooks.*FROMauthors,booksWHEREbooks.author_id=authors.idANDauthors.name=?",
array($name));
$rows=array();
while($res->fetchInto($row)){$rows[]=$row;}
return$rows;
}
$books=get_books('JackHerrington');
var_dump($books);
?>
现在检索列表需要一个快速、单个的查询。这意味着我将很可能必须具有几个这些类型的具有不同参数的方法,但是实在是没有选择。如果您想要具有一个扩展的PHP应用程序,那么必须有效地使用数据库,这意味着更智能的查询。
本例的问题是它有点太清晰了。通常来说,这些类型的n+1或n*n问题要微妙得多。并且它们只有在数据库管理员在系统具有性能问题时在系统上运行查询剖析器时才会出现。
结束语
数据库是强大的工具,就跟所有强大的工具一样,如果您不知道如何正确地使用就会滥用它们。识别和解决这些问题的诀窍是更好地理解底层技术。长期以来,我老听到业务逻辑编写人员抱怨,他们不想要必须理解数据库或SQL代码。他们把数据库当成对象使用,并疑惑性能为什么如此之差。
他们没有认识到,理解SQL对于将数据库从一个困难的必需品转换成强大的联盟是多么重要。如果您每天使用数据库,但是不熟悉SQL,那么请阅读TheArtofSQL,这本书写得很好,实践性也很强,可以指导您基本了解数据库。
idMEDIUMINTNOTNULLAUTO_INCREMENT,
author_idMEDIUMINTNOTNULL,
nameTEXTNOTNULL,
PRIMARYKEY(id)
);
INSERTINTOauthorsVALUES(null,'JackHerrington');
INSERTINTOauthorsVALUES(null,'DaveThomas');
INSERTINTObooksVALUES(null,1,'CodeGenerationinAction');
INSERTINTObooksVALUES(null,1,'PodcastingHacks');
INSERTINTObooksVALUES(null,1,'PHPHacks');
INSERTINTObooksVALUES(null,2,'PragmaticProgrammer');
INSERTINTObooksVALUES(null,2,'Rubyalign=centerbgColor=#e7e9e9border=1>
require_once('DB.php');
$dsn='mysql://root:password@localhost/good_books';
$db=&DB::Connect($dsn,array());
if(PEAR::isError($db)){die($db->getMessage());}
functionget_author_id($name)
{
global$db;
$res=$db->query("SELECTidFROMauthorsWHEREname=?",array($name));
$id=null;
while($res->fetchInto($row)){$id=$row[0];}
return$id;
}
functionget_books($id)
{
global$db;
$res=$db->query("SELECTidFROMbooksWHEREauthor_id=?",array($id));
$ids=array();
while($res->fetchInto($row)){$ids[]=$row[0];}
return$ids;
}
functionget_book($id)
{
global$db;
$res=$db->query("SELECT*FROMbooksWHEREid=?",array($id));
while($res->fetchInto($row)){return$row;}
returnnull;
}
$author_id=get_author_id('JackHerrington');
$books=get_books($author_id);
foreach($booksas$book_id){
$book=get_book($book_id);
var_dump($book);
}
?>
如果您看看下面的代码,您可能会想,“嘿,这才是真正的清楚明了。”首先,得到作者id,然后得到书籍列表,然后得到有关每本书的信息。的确,它很清楚明了,但是其高效吗?回答是否定的。看看只是检索JackHerrington的书籍时要执行多少次查询。一次获得id,另一次获得书籍列表,然后每本书执行一次查询。三本书要执行五次查询!
解决方案是用一个函数来执行大量的查询,如下所示。
清单16.Get_good.php
require_once('DB.php');
$dsn='mysql://root:password@localhost/good_books';
$db=&DB::Connect($dsn,array());
if(PEAR::isError($db)){die($db->getMessage());}
functionget_books($name)
{
global$db;
$res=$db->query("SELECTbooks.*FROMauthors,booksWHEREbooks.author_id=authors.idANDauthors.name=?",
array($name));
$rows=array();
while($res->fetchInto($row)){$rows[]=$row;}
return$rows;
}
$books=get_books('JackHerrington');
var_dump($books);
?>
现在检索列表需要一个快速、单个的查询。这意味着我将很可能必须具有几个这些类型的具有不同参数的方法,但是实在是没有选择。如果您想要具有一个扩展的PHP应用程序,那么必须有效地使用数据库,这意味着更智能的查询。
本例的问题是它有点太清晰了。通常来说,这些类型的n+1或n*n问题要微妙得多。并且它们只有在数据库管理员在系统具有性能问题时在系统上运行查询剖析器时才会出现。
结束语
数据库是强大的工具,就跟所有强大的工具一样,如果您不知道如何正确地使用就会滥用它们。识别和解决这些问题的诀窍是更好地理解底层技术。长期以来,我老听到业务逻辑编写人员抱怨,他们不想要必须理解数据库或SQL代码。他们把数据库当成对象使用,并疑惑性能为什么如此之差。
他们没有认识到,理解SQL对于将数据库从一个困难的必需品转换成强大的联盟是多么重要。如果您每天使用数据库,但是不熟悉SQL,那么请阅读TheArtofSQL,这本书写得很好,实践性也很强,可以指导您基本了解数据库。
