id; }
$id = add_user( 'jerry', 'pass' );
var_dump( $id ); ?>
add_user.php 中的代码首先执行一个查询以找到 id 的最大值。然后文件以 id 值加 1 运行一个 INSERT 语句。该代码在负载很重的服务器上会在竞态条件中失败。另外,它也效率低下。
那么替代方案是什么呢?使用 MySQL 中的自动增量特性来自动地为每个插入创建惟一的 ID。更新后 的模式如下所示。
清单 5. Goodid.php
DROP TABLE IF EXISTS users; CREATE TABLE users ( id MEDIUMINT NOT NULL AUTO_INCREMENT, login TEXT NOT NULL, password TEXT NOT NULL, PRIMARY KEY( id ) );
INSERT INTO users VALUES ( null, 'jack', 'pass' ); INSERT INTO users VALUES ( null, 'joan', 'pass' ); INSERT INTO users VALUES ( null, 'jane', 'pass' );
我们添加了 NOT NULL 标志来指示字段必须不能为空。我们还添加了 AUTO_INCREMENT 标志来指示字段 是自动增量的,添加 PRIMARY KEY 标志来指示那个字段是一个 id。这些更改加快了速度。清单 6 展 示了更新后的 PHP 代码,即将用户插入表中。
清单 6. Add_user_good.php
function add_user( $name, $pass ) { $dsn = 'my
sql://root:pass
word@localhost/good_genid'; $db =&; DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); }
$sth = $db->prepare( "INSERT INTO users VALUES(null,?,?)" ); $db->execute( $sth, array( $name, $pass ) );
$res = $db->query( "SELECT last_insert_id()" ); $id = null; while( $res->fetchInto( $row ) ) { $id = $row[0]; }
return $id; }
$id = add_user( 'jerry', 'pass' );
var_dump( $id ); ?>
现在我不是获得最大的 id 值,而是直接使用 INSERT 语句来插入数据,然后使用 SELECT 语句来检索 最后插入的记录的 id。该代码比最初的版本及其相关模式要简单得多,且效率更高。
回页首
问题 3:使用多个数据库 :
偶尔,我们会看到一个应用
程序中,每个表都在一个单独的
数据库中。在非常大的数据库中这样做是合 理的,但是对于一般的应用程序,则不需要这种级别的分割。此外,不能跨数据库执行关系
查询,这会 影响使用关系数据库的整体思想,更不用说跨多个数据库管理表会更困难了。 那么,多个数据库应该是什么样的呢?首先,您需要一些数据。清单 7 展示了分成 4 个文件的这样的 数据。
清单 7. 数据库文件
Files.sql: CREATE TABLE files ( id MEDIUMINT, user_id MEDIUMINT, name TEXT, path TEXT );
Load_files.sql: INSERT INTO files VALUES ( 1, 1, 'test1.jpg', 'files/test1.jpg' ); INSERT INTO files VALUES ( 2, 1, 'test2.jpg', 'files/test2.jpg' );
Users.sql: DROP TABLE IF EXISTS users; CREATE TABLE users ( id MEDIUMINT, login TEXT, password TEXT );
Load_users.sql: INSERT INTO users VALUES ( 1, 'jack', 'pass' ); INSERT INTO users VALUES ( 2, 'jon', 'pass' );
在这些文件的多数据库版本中,您应该将 SQL 语句加载到一个数据库中,然后将 users SQL 语句加 载到另一个数据库中。用于在数据库中查询与某个特定用户相关联的文件的 PHP 代码如下所示。
清单 8. Getfiles.php
function get_user( $name ) { $dsn = 'mysql://root:password@localhost/bad_multi1'; $db =&; DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); }
$res = $db->query( "SELECT id FROM users WHERE login=?", array( $name ) ); $uid = null; while( $res->fetchInto( $row ) ) { $uid = $row[0]; }
return $uid; }
function get_files( $name ) { $uid = get_user( $name );
$rows = array();
$dsn = 'mysql://root:password@localhost/bad_multi2'; $db =&; DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); }
$res = $db->query( "SELECT * FROM files WHERE user_id=?", array( $u