有三種情境一再出現:
- 為 staging 或 CI 建立結構描述——你想要空的資料表結構,好讓測試能對著真實的欄位、索引與約束執行,但你絕對不想把數 GB 的正式環境資料塞進一個用完即丟的環境。
- 只要種子資料——結構描述在目標資料庫裡已經存在,你只需要那些 INSERT 資料列來填充它,而不要那些會跟現有結構衝突的 CREATE 陳述式。
- 去除雜訊——dump 被
logs、sessions、audit_trail或cache這些動輒數千萬列、你從來不想匯入的資料表撐得又肥又大。
為什麼 mysqldump --no-data 還不夠
經典建議是 mysqldump --no-data(只要結構)或 mysqldump --no-create-info(只要資料)。兩者都是匯出旗標:它們改變的是一份從執行中資料庫新匯出的 dump 會包含什麼。對於你已經放在磁碟上的 .sql 檔案,它們毫無作用。
實務上,這個檔案往往是別人給的、來自某個備份工作,或來自一台你已無法即時存取的伺服器。你沒辦法對一個連不上的資料庫重新執行 mysqldump——憑證不見了、伺服器已退役,或者這個檔案就是別人交給你的全部。到了這一步,那些旗標毫無用處,你只能自己去編輯檔案本身。
手動的做法
最直覺的做法是用 grep 或 sed 剝掉某些行。想保留結構、去掉資料:
# 保留 INSERT 資料列以外的所有內容 grep -v '^INSERT INTO' dump.sql > schema.sql # 或只保留 INSERT 資料列,做出只含資料的檔案 grep '^INSERT INTO' dump.sql > data.sql
這在小巧整齊的 dump 上看起來沒問題——然後就在真實的 dump 上崩掉:
- 多行 INSERT。單一個
INSERT INTO … VALUES可能橫跨數千行。grep只比對到第一行,其餘的值全被孤立,產出一個壞掉的檔案。 - 擴充式 insert。mysqldump 會把許多資料列打包成一個巨大的陳述式。以行為單位的過濾器根本分不出這樣的陳述式在哪裡結束。
- 註解與區塊。條件式的
/*! … */區塊、LOCK TABLES以及--註解會與資料交錯,所以粗糙的過濾器要嘛留下垃圾,要嘛切掉匯入所需的東西。 - 只要資料更糟。單純的
grep '^INSERT'會丟掉資料列所依賴的SET與LOCK陳述式,而且任何不是剛好從第 0 欄開始的 INSERT 都會悄悄消失。
最後你不是在拿到結構描述,而是在除錯自己寫的過濾器。
用 DumpCleaner 只取結構或只取資料
DumpCleaner 理解 SQL 陳述式,而不是逐行比對,所以它能可靠地把結構與資料分離——不論檔案多大:
- 把你的
.sqldump 拖進 DumpCleaner(MySQL、MariaDB 或 PostgreSQL)。它以串流解析檔案,所以數 GB 的 dump 是以恆定記憶體載入。 - 切換你要的陳述式類型:CREATE TABLE、CREATE INDEX、INSERT INTO、ALTER、DROP、LOCK、SET。取消勾選 INSERT INTO 就只剩結構;取消勾選 CREATE TABLE / CREATE INDEX 就只剩資料。
- 或選一個預設集——只要結構或只要資料——一步設定好所有切換,之後再依資料表微調也行。
- 匯出。你會得到一份適合 staging 或 CI 的精簡結構描述檔案,或一份適合灌種子資料、只含資料的乾淨 dump。
因為過濾是以陳述式為單位,一個多行的擴充式 INSERT 會被整段保留或整段去掉——絕不會從中間被切斷。
真正強大的地方在於,過濾能依陳述式類型與依資料表運作,而且兩者可以組合。你可以保留每一個資料表的結構,卻只為你真正需要的那三個資料表納入 INSERT 資料——讓那個 8,900 萬列的 logs 資料表變成一個空殼。這是任何 --no-data 旗標都表達不出來的。
幾秒內把結構與資料分離
DumpCleaner 依陳述式類型與資料表過濾現有 dump——只要結構、只要資料,或任意組合——採串流處理、記憶體恆定。原生 macOS & iPadOS App,一次性買斷。
在 App Store 下載常見問題
我可以只匯出資料而不要結構描述嗎?
可以。停用 CREATE TABLE 和 CREATE INDEX(或選「只要資料」預設集),並保留 INSERT INTO。DumpCleaner 只匯出那些資料列,可直接載入一個已存在的結構描述。
只匯出結構會保留索引和外鍵嗎?
會。只要結構會保留 CREATE TABLE、CREATE INDEX、ALTER TABLE 以及外鍵定義——所有定義資料庫的東西。只有 INSERT 資料列會被移除。
我可以混搭嗎——所有資料表保留結構,部分資料表保留資料?
可以。過濾是以陳述式類型與資料表為單位,兩者可組合。保留每個資料表的結構,卻只為你真正需要的那幾個資料表納入 INSERT 資料。
這對 PostgreSQL 也有效嗎?
有效。DumpCleaner 能讀取 MySQL、MariaDB 與 PostgreSQL dump,並自動偵測格式,所以只要結構與只要資料的匯出對 pg_dump 檔案運作方式完全相同。