PHP数据库常出现哪些问题?(4)

http://www.itjxue.com  2015-07-17 08:18  来源:未知  点击次数: 

该代码不仅更短,而且也更容易理解和高效。我们不是执行两个查询,而是执行一个查询。

尽管该问题听起来有些牵强,但是在实践中我们通常总结出所有的表应该在同一个数据库中,除非有非常迫不得已的理由。

问题 4:不使用关系

关系数据库不同于编程语言,它们不具有数组类型。相反,它们使用表之间的关系来创建对象之间的一到多结构,这与数组具有相同的效果。我在应用程序中看到的一个问题是,工程师试图将数据库当作编程语言来使用,即通过使用具有逗号分隔的标识符的文本字符串来创建数组。请看下面的模式。


DROP TABLE IF EXISTS files;
CREATE TABLE files (
id MEDIUMINT,
name TEXT,
path TEXT
);

DROP TABLE IF EXISTS users;
CREATE TABLE users (
id MEDIUMINT,
login TEXT,
password TEXT,
files TEXT
);

INSERT INTO files VALUES ( 1, 'test1.jpg', 'media/test1.jpg' );
INSERT INTO files VALUES ( 2, 'test1.jpg', 'media/test1.jpg' );
INSERT INTO users VALUES ( 1, 'jack', 'pass', '1,2' );


清单 10. Bad.sql
系统中的一个用户可以具有多个文件。在编程语言中,应该使用数组来表示与一个用户相关联的文件。在本例中,程序员选择创建一个 files 字段,其中包含一个由逗号分隔的文件 id 列表。要得到一个特定用户的所有文件的列表,程序员必须首先从用户表中读取行,然后解析文件的文本,并为每个文件运行一个单独的 SELECT 语句。该代码如下所示。


<?php
require_once("DB.php");

function get_files( $name )
{
$dsn = 'mysql://root:password@localhost/bad_norel';
$db =& DB::Connect( $dsn, array() );
if (PEAR::isError($db)) { die($db->getMessage()); }

$res = $db->query( "SELECT files FROM users WHERE login=?",
array( $name ) );
$files = null;
while( $res->fetchInto( $row ) ) { $files = $row[0]; }

$rows = array();

foreach( split( ',',$files ) as $file )
{
  $res = $db->query( "SELECT * FROM files WHERE id=?",
    array( $file ) );
  while( $res->fetchInto( $row ) ) { $rows[] = $row; }
}

return $rows;
}

$files = get_files( 'jack' );

var_dump( $files );
?>


清单 11. Get.php
该技术很慢,难以维护,且没有很好地利用数据库。惟一的解决方案是重新架构模式,以将其转换回到传统的关系形式,如下所示。


DROP TABLE IF EXISTS files;
CREATE TABLE files (
id MEDIUMINT,
user_id MEDIUMINT,
name TEXT,
path TEXT
);

DROP TABLE IF EXISTS users;
CREATE TABLE users (
id MEDIUMINT,
login TEXT,
password TEXT
);

INSERT INTO users VALUES ( 1, 'jack', 'pass' );
INSERT INTO files VALUES ( 1, 1, 'test1.jpg', 'media/test1.jpg' );
INSERT INTO files VALUES ( 2, 1, 'test1.jpg', 'media/test1.jpg' );


清单 12. Good.sql
这里,每个文件都通过 user_id 函数与文件表中的用户相关。这可能与任何将多个文件看成数组的人的思想相反。当然,数组不引用其包含的对象 —— 事实上,反之亦然。但是在关系数据库中,工作原理就是这样的,并且查询也因此要快速且简单得多。清单 13 展示了相应的 PHP 代码。


<?php
require_once("DB.php");

function get_files( $name )
{
$dsn = 'mysql://root:password@localhost/good_rel';
$db =& DB::Connect( $dsn, array() );
if (PEAR::isError($db)) { die($db->getMessage()); }

$rows = array();
$res = $db->query(
  "SELECT files.* FROM users,files WHERE users.login=?
    AND users.id=files.user_id",
    array( $name ) );
while( $res->fetchInto( $row ) ) { $rows[] = $row; }

return $rows;
}

$files = get_files( 'jack' );

var_dump( $files );
?>

清单 13. Get_good.php 

(责任编辑:IT教学网)

更多