模式切换
数据库操作
PHP 与 MySQL 的连接
- 使用 PDO 连接 MySQL
PDO(PHP Data Objects)是一种轻量级的数据库访问抽象层,支持多种数据库。
php
try {
$pdo = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
- 使用 MySQLi 连接 MySQL
MySQLi(MySQL Improved)提供面向过程和面向对象的两种编程方式。
php
// 面向对象方式
$mysqli = new mysqli("localhost", "username", "password", "testdb");
if ($mysqli->connect_error) {
die("Connection failed: " . $mysqli->connect_error);
}
echo "Connected successfully";
SQL 基础
- 查询(SELECT):
php
// 使用 PDO
$stmt = $pdo->query("SELECT * FROM users");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['name'] . "<br>";
}
// 使用 MySQLi
$result = $mysqli->query("SELECT * FROM users");
while ($row = $result->fetch_assoc()) {
echo $row['name'] . "<br>";
}
- 插入(INSERT):
php
// 使用 PDO
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->execute(['name' => 'John Doe', 'email' => 'john@example.com']);
// 使用 MySQLi
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
$name = "John Doe";
$email = "john@example.com";
$stmt->execute();
- 更新(UPDATE):
php
// 使用 PDO
$stmt = $pdo->prepare("UPDATE users SET email = :email WHERE name = :name");
$stmt->execute(['email' => 'john_new@example.com', 'name' => 'John Doe']);
// 使用 MySQLi
$stmt = $mysqli->prepare("UPDATE users SET email = ? WHERE name = ?");
$stmt->bind_param("ss", $email, $name);
$email = "john_new@example.com";
$name = "John Doe";
$stmt->execute();
- 删除(DELETE):
php
// 使用 PDO
$stmt = $pdo->prepare("DELETE FROM users WHERE name = :name");
$stmt->execute(['name' => 'John Doe']);
// 使用 MySQLi
$stmt = $mysqli->prepare("DELETE FROM users WHERE name = ?");
$stmt->bind_param("s", $name);
$name = "John Doe";
$stmt->execute();
预处理语句与防止 SQL 注入
- 预处理语句:
使用占位符(如 :name
或 ?
)来避免 SQL 注入攻击。
php
// PDO 预处理
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => 'john@example.com']);
$result = $stmt->fetchAll();
// MySQLi 预处理
$stmt = $mysqli->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$email = "john@example.com";
$stmt->execute();
$result = $stmt->get_result();
- 防止 SQL 注入:
始终使用预处理语句,不要直接拼接用户输入的数据到 SQL 语句中。
数据库事务
事务的使用:
在数据库操作中使用事务可以确保多条语句要么全部成功,要么全部失败。
php
// 使用 PDO
try {
$pdo->beginTransaction();
$pdo->exec("INSERT INTO accounts (user, balance) VALUES ('Alice', 1000)");
$pdo->exec("INSERT INTO accounts (user, balance) VALUES ('Bob', 500)");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}
// 使用 MySQLi
$mysqli->begin_transaction();
try {
$mysqli->query("INSERT INTO accounts (user, balance) VALUES ('Alice', 1000)");
$mysqli->query("INSERT INTO accounts (user, balance) VALUES ('Bob', 500)");
$mysqli->commit();
} catch (Exception $e) {
$mysqli->rollback();
echo "Failed: " . $e->getMessage();
}
数据库的优化
索引:
为常用的查询字段添加索引,可以显著提高查询速度。
sql
CREATE INDEX idx_user_email ON users (email);
查询优化:
- 避免使用
SELECT *
:只查询需要的字段。 - 使用适当的 WHERE 条件:限制返回的行数,减少不必要的数据传输。
- 缓存结果:使用数据库缓存或 Redis 等外部缓存来加快响应速度。
数据库表优化:
定期优化表:清理碎片,保持表的性能。
sql
OPTIMIZE TABLE users;
分表和分库:
当数据量非常大时,可以考虑将数据分成多个表或数据库存储,分散负载。