在多項目、多環境、多租戶場景下,頻繁手動執行 CREATE DATABASE、GRANT 等 DDL 語句不僅低效,極易出錯。利用 MySQL 客戶端的 文件導入執行特性(mysql < file.sql),可將批量建庫、授權、刷新權限封裝為單個 SQL 腳本,實現一鍵部署、版本控制與跨環境復用。本文詳解腳本編寫規範、執行方式與進階技巧。
MySQL 客戶端支援從標準輸入或文件讀取 SQL 語句並順序執行:
mysql -u root -p [db_name] < script.sql
; 結尾。-- 或 #)與流程控制(僅限存儲過程/觸發器內)。--force 強制或編寫事務控制邏輯。創建 init_db_user.sql:
-- 目標:創建數據庫 app_db,用戶 app_user@localhost,密碼 StrongPass123!
CREATE DATABASE IF NOT EXISTS `app_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 授權:僅本地訪問,具備增刪改查、建表、索引、執行等常用權限
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE
ON `app_db`.* TO 'app_user'@'localhost' IDENTIFIED BY 'StrongPass123!';
-- 刷新權限立即生效
FLUSH PRIVILEGES;
執行命令:
mysql -u root -p < init_db_user.sql
輸入 root 密碼後自動完成建庫授權。
利用 變量佔位 + Shell/Python 模板渲染 或直接編寫重複塊,實現批量:
-- 批量初始化 3 個項目庫與用戶
-- 項目 1
CREATE DATABASE IF NOT EXISTS `proj_alpha` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON `proj_alpha`.* TO 'alpha_user'@'%' IDENTIFIED BY 'AlphaPass2024!';
FLUSH PRIVILEGES;
-- 項目 2
CREATE DATABASE IF NOT EXISTS `proj_beta` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON `proj_beta`.* TO 'beta_user'@'%' IDENTIFIED BY 'BetaPass2024!';
FLUSH PRIVILEGES;
-- 項目 3
CREATE DATABASE IF NOT EXISTS `proj_gamma` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON `proj_gamma`.* TO 'gamma_user'@'%' IDENTIFIED BY 'GammaPass2024!';
FLUSH PRIVILEGES;
最佳實踐: 實際專案中,建議使用 Shell 腳本 + 變量數組 或 Python/Jinja2 模板 動態生成上述 SQL,避免手工複製修改導致拼寫錯誤。
#!/bin/bash
# batch_create_db_user.sh
# 用法:./batch_create_db_user.sh > init_all.sql
DBS=("proj_alpha:alpha_user:AlphaPass2024!" "proj_beta:beta_user:BetaPass2024!" "proj_gamma:gamma_user:GammaPass2024!")
echo "-- Auto-generated at $(date)"
for entry in "${DBS[@]}"; do
IFS=':' read -r db user pass <<< "$entry"
cat <
執行 ./batch_create_db_user.sh > init_all.sql 即可生成標準化 SQL 文件,納入版本控制。
mysql -u root -p < init_all.sqlmysql -u root -p -e "SHOW DATABASES;"mysql -u root -p -e "SHOW GRANTS FOR 'alpha_user'@'%';"mysql -u alpha_user -p'AlphaPass2024!' -h localhost proj_alpha -e "SELECT 1;"| 項目 | 說明 |
|---|---|
| 密碼特殊字符轉義 | SQL 文件中密碼含單引號、反斜杠、美元符等需轉義(如 \', \\),或使用 IDENTIFIED BY '...' 單引號包裹並在 Shell 層面處理轉義。 |
| 主機名 '%' vs 'localhost' | % 允許任意 IP 連接(含遠程),localhost 僅允許本地 Unix Socket 連接。生產環境建議按最小權限原則指定具體 IP 或網段(如 '10.0.%')。 |
| 權限最小化 | 避免 GRANT ALL PRIVILEGES 或 *.*。僅授予業務必需權限(通常:SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,INDEX,EXECUTE)。 |
| 字符集統一 | 強制指定 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,防止跨環境字符集不一致導致亂碼。 |
| 冪等性 | 使用 IF NOT EXISTS、DROP USER IF EXISTS(MySQL 5.7.6+)確保腳本可重複執行不報錯。 |
| 事務不支援 DDL | CREATE DATABASE、GRANT 隱式提交,無法回滾。腳本按依賴順序編排,關鍵步驟前備份數據。 |
MySQL 官方 Docker 映像支援 /docker-entrypoint-initdb.d/ 目錄下的 .sql/.sh/.sql.gz 文件容器首次啟動時自動執行:
# Dockerfile
FROM mysql:5.7
COPY init_all.sql /docker-entrypoint-initdb.d/
# 或 COPY batch_create_db_user.sh /docker-entrypoint-initdb.d/
實現「鏡像內置初始化邏輯,啟動即就緒」,極大簡化 CI/CD 流水線。
mysql < script.sql 是 MySQL 批量 DDL 操作的「瑞士軍刀」。將建庫、授權、字符集設置標準化為 SQL 腳本,再配合 Shell/Python 模板化生成、納入 Git 版本控制、接入 Docker 自動初始化,即可構建可審計、可復用、可自動化的數據庫基礎設施交付流程。從手工敲命令進化到基礎設施即代碼,始於一個規範的 SQL 文件。