首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 表數據清空、刪除與結構修改操作詳解

     編輯:MySQL 資料庫相關知識

一、清空表數據:TRUNCATE vs DELETE

特性TRUNCATE TABLEDELETE FROM (無 WHERE)
執行速度極快 (元數據操作,重建表)慢 (逐行刪除,記錄 Binlog)
事務性隱式提交,不可回滾可回滾 (需在事務中)
自增計數器重置為 1 (或初始值)保持不變
觸發器不觸發 ON DELETE觸發每行 ON DELETE
外鍵約束被引用表不可 TRUNCATE受外鍵限制 (RESTRICT/CASCADE)
權限需求DROP + CREATE 權限DELETE 權限
Binlog 記錄記錄為 DDL (STATEMENT 格式)記錄每行刪除 (ROW 格式)
適用場景清空全表、重置測試數據、日志輪轉需保留自增值、需觸發器、需回滾
-- 清空表
TRUNCATE TABLE `user_log`;

-- 等效於 (但更快)
DROP TABLE `user_log`;
CREATE TABLE `user_log` LIKE `user_log`;  -- 結構克隆

二、條件刪除數據

基本語法

DELETE FROM `table_name` WHERE condition [ORDER BY ...] [LIMIT row_count];

實戰範例

-- 1. 單條件刪除
DELETE FROM `order` WHERE status = 0 AND created_at < '2023-01-01';

-- 2. 多表關聯刪除 (刪除無用戶的訂單)
DELETE o FROM `order` o
LEFT JOIN `user` u ON o.user_id = u.id
WHERE u.id IS NULL;

-- 3. 刪除重複數據 (保留最小 id)
DELETE t1 FROM `user` t1
INNER JOIN `user` t2
WHERE t1.email = t2.email AND t1.id > t2.id;

-- 4. 分批刪除大量數據 (避免長事務鎖表)
-- 存儲過程示例
DELIMITER //
CREATE PROCEDURE batch_delete_old_logs()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE batch_size INT DEFAULT 1000;
    REPEAT
        DELETE FROM `access_log` 
        WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY)
        LIMIT batch_size;
        SET done = ROW_COUNT();
        -- 可選:SLEEP(0.1) 降低主從延遲
    UNTIL done < batch_size END REPEAT;
END //
DELIMITER ;

三、修改表結構 (ALTER TABLE)

1. 列操作

-- 增加列
ALTER TABLE `user` ADD COLUMN `phone` VARCHAR(16) NOT NULL DEFAULT '' AFTER `email`;
ALTER TABLE `user` ADD COLUMN `nickname` VARCHAR(32) NOT NULL DEFAULT '' FIRST;

-- 修改列定義 (類型/長度/默認值/註釋/非空)
ALTER TABLE `user` MODIFY COLUMN `status` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '狀態';

-- 重命名列 (需完整重新指定定義)
ALTER TABLE `user` CHANGE COLUMN `phone` `mobile` VARCHAR(16) NOT NULL DEFAULT '';

-- 刪除列
ALTER TABLE `user` DROP COLUMN `mobile`;

2. 索引操作

-- 增加普通索引
ALTER TABLE `user` ADD INDEX `idx_status` (`status`);

-- 增加唯一索引
ALTER TABLE `user` ADD UNIQUE KEY `uk_mobile` (`mobile`);

-- 增加主鍵 (表無主鍵時)
ALTER TABLE `user` ADD PRIMARY KEY (`id`);

-- 增加聯合索引
ALTER TABLE `order` ADD INDEX `idx_user_status` (`user_id`, `status`);

-- 刪除索引
ALTER TABLE `user` DROP INDEX `idx_status`;

3. 外鍵操作

-- 增加外鍵
ALTER TABLE `order` 
ADD CONSTRAINT `fk_order_user` 
FOREIGN KEY (`user_id`) REFERENCES `user`(`id`)
ON UPDATE CASCADE ON DELETE RESTRICT;

-- 刪除外鍵
ALTER TABLE `order` DROP FOREIGN KEY `fk_order_user`;

4. 表選項修改

-- 轉換引擎 (重建表,鎖表)
ALTER TABLE `user` ENGINE = InnoDB;

-- 修改自增起始值
ALTER TABLE `user` AUTO_INCREMENT = 10000;

-- 修改表字符集 (僅影響新列)
ALTER TABLE `user` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 修改表及所有列字符集 (重建表)
ALTER TABLE `user` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 修改表註釋
ALTER TABLE `user` COMMENT = '用戶核心信息表';

5. 重命名表

-- 單表重命名
RENAME TABLE `user` TO `user_v1`;

-- 多表原子交換 (常用於發布回滾)
RENAME TABLE `user` TO `user_old`, `user_new` TO `user`;

-- 跨庫移動
RENAME TABLE `db1`.`user` TO `db2`.`user`;

四、表維護與優化

-- 1. 更新統計信息 (優化器決策依據)
ANALYZE TABLE `user`;

-- 2. 整理碎片、回收空間 (重建表,InnoDB 等同於 ALTER TABLE ... ENGINE=InnoDB)
OPTIMIZE TABLE `user`;

-- 3. 檢查表損壞
CHECK TABLE `user` [QUICK | FAST | MEDIUM | EXTENDED | CHANGED];

-- 4. 修復表 (主要針對 MyISAM,InnoDB 自動崩潰恢復)
REPAIR TABLE `user` [QUICK | EXTENDED | USE_FRM];

五、數據導入導出 (文件級)

-- 導出 (需 FILE 權限、secure_file_priv 目錄)
SELECT id, username, email 
FROM `user` 
WHERE status = 1 
INTO OUTFILE '/var/lib/mysql-files/user_export.csv'
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

-- 導入
LOAD DATA INFILE '/var/lib/mysql-files/user_export.csv'
INTO TABLE `user`
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'
IGNORE 1 LINES
(id, username, email);  -- 可指定列映射順序

六、無鎖變更大表結構 (pt-online-schema-change)

# 安裝 Percona Toolkit
yum install -y percona-toolkit

# 無鎖增加列
pt-online-schema-change \
    --alter "ADD COLUMN phone VARCHAR(16) NOT NULL DEFAULT ''" \
    D=app_db,t=user \
    --execute \
    --max-load "Threads_running=100" \
    --critical-load "Threads_running=200" \
    --chunk-size 1000 \
    --progress time,30
  • 原理:建影子表 → 拷貝數據 → 捕獲增量 (觸發器) → 同步 → 原子重命名
  • 適用:大表 (>1GB/>1000萬行) 加列、改類型、加索引、修改字符集
  • 限制:需主鍵/唯一鍵;無觸發器;外鍵需特殊處理

七、權限最小化原則

-- 僅授予必要權限
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_rw'@'10.0.%';
GRANT ALTER, CREATE, INDEX ON app_db.* TO 'dev_ops'@'10.0.%';  -- 變更結構權限分離
GRANT TRUNCATE ON app_db.user_log TO 'cron_job'@'10.0.%';      -- 僅清空日志表權限

掌握上述操作的語法細節、性能特徵與適用邊界,能讓你在日常開發、線上變更、故障恢復中游刃有餘,避免「一條 DELETE 搞掛主庫」的慘劇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved