| 索引類型 | 建立語法 | 特性 | 適用場景 |
| PRIMARY KEY | 欄位級或表級 | 叢集索引、唯一、非空、單表僅一個 | 主鍵 ID |
| UNIQUE INDEX | UNIQUE INDEX idx_email (email) | 唯一、允許 NULL、非叢集 | Email、用戶名、身分證號 |
| INDEX / KEY | INDEX idx_name (lastname, firstname) | 非唯一、非叢集、支援前綴 | 常用 WHERE/JOIN/ORDER BY 欄位 |
| FULLTEXT | FULLTEXT INDEX idx_content (content) | 全文搜尋,MyISAM/InnoDB 5.6+ | 文章搜尋、日誌分析 |
| SPATIAL | SPATIAL INDEX idx_location (geo_point) | 地理空間,InnoDB 5.7+ | GIS 應用 |
| 複合索引 | INDEX idx_a_b (a, b) | 最左前綴原則,順序關鍵 | 多欄位組合查詢 |
表選項
CREATE TABLE MyGuests (...)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
ROW_FORMAT=DYNAMIC
COMMENT='用戶資訊表';
- ENGINE:
InnoDB (預設、支援交易/外鍵/行鎖) / MyISAM (舊版、全文索引、表鎖) / MEMORY (記憶體表)
- CHARSET:utf8mb4 (支援完整 Unicode 含 Emoji),勿用 utf8 (僅 BMP)
- COLLATE:
utf8mb4_unicode_ci (標準 Unicode 排序) / utf8mb4_general_ci (較快但排序較粗略)
- ROW_FORMAT:
DYNAMIC (InnoDB 預設、支援壓縮、長字串溢位頁)
完整建表示例:用戶資訊表
$sql = <<
MySQLi 物件導向建表
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
if ($mysqli->connect_error) die("連線失敗: " . $mysqli->connect_error);
if ($mysqli->query($sql) === true) {
echo "資料表建立成功";
} else {
echo "建立失敗: " . $mysqli->error;
}
$mysqli->close();
MySQLi 程序式建表
$conn = mysqli_connect('localhost', 'user', 'pass', 'db');
if (!$conn) die("連線失敗: " . mysqli_connect_error());
if (mysqli_query($conn, $sql)) {
echo "資料表建立成功";
} else {
echo "建立失敗: " . mysqli_error($conn);
}
mysqli_close($conn);
PDO 建表
$pdo = new PDO("mysql:host=localhost;dbname=db", 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$pdo->exec($sql); // exec() 用於無結果集 DDL/DML
echo "資料表建立成功";
} catch (PDOException $e) {
echo "建立失敗: " . $e->getMessage();
}
$pdo = null;
檢查表是否存在、結構資訊
// 1. SHOW TABLES LIKE 'users'
$exists = $pdo->query("SHOW TABLES LIKE 'users'")->rowCount() > 0;
// 2. DESCRIBE / SHOW COLUMNS
$cols = $pdo->query("DESCRIBE `users`")->fetchAll(PDO::FETCH_ASSOC);
// 3. SHOW CREATE TABLE
$createSql = $pdo->query("SHOW CREATE TABLE `users`")->fetchColumn();
// 4. INFORMATION_SCHEMA (跨資料庫、程式化)
$tables = $pdo->query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db'")->fetchAll(PDO::FETCH_COLUMN);
常見設計錯誤與優化建議
| 錯誤 | 影響 | 修正 |
| 使用 INT(11) 顯示寬度 | 無實際效果,誤導開發者 | 僅用 INT,應用層控制顯示 |
| 金額用 FLOAT/DOUBLE | 精度誤差導致金額錯誤 | 必用 DECIMAL(10,2) 或 DECIMAL(19,4) |
| VARCHAR(255) 通用 | 浪費空間、索引效能差 | 依業務實際長度設定 (如 email 100、手機 20) |
| 缺少 NOT NULL | NULL 語意模糊、索引效能差 | 業務必填欄位加 NOT NULL |
| 缺少 updated_at 自動更新 | 手動維護易遺漏 | ON UPDATE CURRENT_TIMESTAMP |
| 使用 utf8 而非 utf8mb4 | 無法儲存 Emoji、部分生僻字 | 全庫 utf8mb4 |
| 大量索引未評估 | 寫入效能下降、空間浪費 | 依實際查詢模式建立、定期審視 |
總結
建立資料表是資料庫應用的基礎工程。掌握 資料型別精準選擇、約束條件完整定義、索引策略科學規劃、字元集統一 utf8mb4、引擎選擇 InnoDB,並透過 PDO 統一介面執行 DDL,能奠定高效能、可擴展、資料一致性的堅實基礎。代碼中建議使用 Heredoc 多行字串維護 SQL 可讀性,並納入版本控管遷移腳本 (Migration) 管理結構演進。
- 上一篇文章: PHP MySQL 插入資料完整指南:INSERT 語法、MySQLi/PDO 實作與安全最佳實務
- 下一篇文章: PHP MySQL 建立資料庫完整指南:CREATE DATABASE、字元集配置、權限與三大介面實作
Copyright ©
程式碼之家 All Rights Reserved