CREATE TABLE 是資料庫結構設計的起點。一張良好的表結構:欄位類型精準、約束完整、索引合理、命名規範,能為後續開發、查詢效能、資料品質奠定堅實基礎。本文系統講解語法要素、核心約束、命令列與 PHP 實戰,並分享建表最佳實踐。
CREATE TABLE [IF NOT EXISTS] table_name (
column_name column_type [column_attributes] [column_constraints],
...,
[table_constraints]
) [table_options];
IF NOT EXISTS:表已存在時不報錯,部署腳本必加。column_attributes:NOT NULL、DEFAULT、AUTO_INCREMENT、COMMENT 等。column_constraints:PRIMARY KEY、UNIQUE、CHECK(8.0.16+ 生效)。table_constraints:複合主鍵、外鍵、複合唯一、CHECK 等。table_options:ENGINE=InnoDB、CHARSET=utf8mb4、COLLATE=utf8mb4_general_ci、PARTITION BY... 等。CREATE TABLE runoob_tbl (
runoob_id INT NOT NULL AUTO_INCREMENT,
runoob_title VARCHAR(100) NOT NULL,
runoob_author VARCHAR(40) NOT NULL,
submission_date DATE,
PRIMARY KEY (runoob_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
| 欄位 | 類型與屬性 | 含義 |
|---|---|---|
runoob_id | INT NOT NULL AUTO_INCREMENT | 主鍵,自動遞增,不可為空 |
runoob_title | VARCHAR(100) NOT NULL | 標題,最長 100 字符,必填 |
runoob_author | VARCHAR(40) NOT NULL | 作者,最長 40 字符,必填 |
submission_date | DATE | 發布日期,可為 NULL |
插入/更新時若給 NULL 直接報錯 Error 1364。業務必填欄位務必加 NOT NULL,資料庫層面攔截,比應用層驗證更可靠。
ALTER TABLE tbl AUTO_INCREMENT=1000; 調整起始值。NOT NULL + UNIQUE。CREATE TABLE orders (
status ENUM('pending','paid','shipped') NOT NULL DEFAULT 'pending',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
mysql> USE RUNOOB;
mysql> CREATE TABLE runoob_tbl(
-> runoob_id INT NOT NULL AUTO_INCREMENT,
-> runoob_title VARCHAR(100) NOT NULL,
-> runoob_author VARCHAR(40) NOT NULL,
-> submission_date DATE,
-> PRIMARY KEY (runoob_id)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.16 sec)
<?php
$table = 'runoob_tbl';
$allowed = ['runoob_tbl', 'tcount_tbl', 'employee_tbl'];
if (!in_array($table, $allowed)) die('Invalid table');
$sql = "CREATE TABLE IF NOT EXISTS `$table` (
`runoob_id` INT NOT NULL AUTO_INCREMENT,
`runoob_title` VARCHAR(100) NOT NULL,
`runoob_author` VARCHAR(40) NOT NULL,
`submission_date` DATE,
PRIMARY KEY (`runoob_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
$conn = new mysqli('localhost:3306', 'root', 'rootpassword', 'RUNOOB');
if ($conn->connect_error) die('Connect failed: ' . $conn->connect_error);
if ($conn->query($sql)) {
echo "Table `$table` created successfully\n";
} else {
echo "Create failed: " . $conn->error;
}
$conn->close();
?>
snake_case,無保留字、無特殊字符。COLLATE utf8mb4_general_ci 或 0900_ai_ci(8.0+)。SHOW FULL COLUMNS 可見。deleted_at DATETIME NULL DEFAULT NULL 或 is_deleted TINYINT DEFAULT 0。version INT DEFAULT 0 防止並發覆蓋。TEXT/BLOB 超過 64KB 考慮拆分附屬表,主表保持輕量。Error 1075: Incorrect table definition:自增欄位非索引 → 加 PRIMARY KEY 或 UNIQUE KEY。Error 1170: BLOB/TEXT column can't have a default value:TEXT/BLOB 不支援 DEFAULT → 移除或改用 VARCHAR。Error 1067: Invalid default value:日期預設值格式錯誤 → 用 CURRENT_TIMESTAMP 或合法字面值。CREATE TABLE 不是一次性動作,而是隨業務演進持續優化的過程。遵循「約束優於驗證、規範優於自由、遷移優於手改」原則,打造經得起時間考驗的資料骨架。