mysql資料的匯入和匯出
一. mysqldump工具基本用法,不適用於大資料備份
1. 備份所有資料庫: mysqldump -u root -p --all-databases > all_database_sql 2. 備份mysql資料庫:mysqldump -u root -p --databases mysql > mysql_database_sql 3. 備份指定的多個數據庫:mysqldump -u root -p --databases db1 db2 db3 > bak.sql 4. 備份mysql資料庫下的user表:mysqldump -u root -p mysql user > user_table 如果不用--databases選項,在後期進行資料還原操作時,如果該資料庫不存在,必須先建立該資料庫;而在例子3指定多個數據庫時,必須要加--databases引數,否則db2會被認為是db1庫的表。 把備份的所有資料檔案還原: mysql -u root -p < all_database_sql,這裡不需要指定庫,因為是全部資料庫 mysql -u root -p mysql < mysql_database_sql #這裡就需要指定是mysql庫了二. 匯出純文字資料
在某些情況下,為了一些特定的目的,經常需要將表裡的資料匯出為某些符號分割的純資料文字,而不是 SQL 語句,因為LOAD DATA 的載入速度比普通的 SQL 載入要快 20 倍以上
方法 1:使用 SELECT ...INTO OUTFILE ...命令來匯出資料,具體語法如下。
mysql> SELECT * FROM tablename INTO OUTFILE 'target_file' [option];
其中 option 引數可以是以下選項:
命令引數 | 說明 |
fields terminated by '字元' | 欄位分隔符,預設字元為製表符'\t' |
fields [optionally] enclosed by '單字元' | 欄位引用符,加上optionally後在數字型別上不會有引用符號 |
fields escaped by '單字元' | 轉義字元,預設為'\' |
lines starting by '字元' | 每行前都加此支付,預設為空 |
lines terminated by '字元' | 行結束符,預設為'\n' |
例子1,將 emp 表中資料匯出為資料文字,其中,欄位分隔符為“,”,每個欄位用雙引號引用起來,記錄結束符為回車符(預設如此,可以不寫)
mysql> select * from emp into outfile '/tmp/emp.txt' fields terminated by "," enclosed by '"';
輸出結果如下
mysql> system more /tmp/emp.txt "1","z1","aa" "2","z1","aa" "3","z1","aa"
例子2,發現例1中第一列是數值型,如果不希望欄位兩邊用引號,則語句改為如下
mysql> select * from emp into outfile '/tmp/emp.txt' fields terminated by "," optionally enclosed by '"' ;
結果輸出如下mysql> system more /tmp/emp.txt 1,"z1","aa" 2,"z1","aa" 3,"z1","aa"
下面測試一下轉義字元,大概包括三類,轉義字元本身,欄位分隔符(匯出的文字中用什麼符號分隔),記錄分隔符(每條記錄之間用什麼分隔,預設是回車)
例子3,更改上面例子中id=1的name為\"##!aa
update employee set name ='\\"##!aa' where id=1; #更新操作中轉義字元本身也需要用轉義字元來轉義,所以這裡有2個\\ # 然後做匯出操作 select * from employee into outfile '/tmp/employee' fields terminated by "," optionally enclosed by ‘”’; 匯出結果如下 mysql> system more /tmp/emp.txt 1,"\\\"##!aa","aa" 2,"z1","aa" 3,"z1","aa"
說明:name 中含有轉義字元本身“\”,域引用符“”“,因此,在輸出的資料中我們發現這兩種字元前面都加上了轉義字元“\”
例子4,將id=1的name更新為含有欄位分隔符”,“的字串
update employee set name='\\"#,#,!aa' where id=1; 然後匯出 mysql> system rm /tmp/emp.txt #需要刪掉重名檔案 mysql> select * from emp into outfile '/tmp/emp.txt' fields terminated by "," optionally enclosed by '"' ; 輸出結果如下 mysql> system more /tmp/emp.txt 1,"\\\"#,#,!aa","aa" 2,"z1","aa" 3,"z1","aa"
說明:發現數據中的字元","沒有被轉義,原因是它和後面真正的欄位分隔符之間沒有衝突,因為name欄位包含在雙引號之間。
例子5:繼續做測試,將輸出檔案的欄位引用符去掉,這個時候,我們的預期是資料中的“,”將成為轉義字元而需要加上“\”
mysql> system rm /tmp/emp.txt mysql> select * from emp into outfile '/tmp/emp.txt' fields terminated by "," ; 輸出結果如下 mysql> system more /tmp/emp.txt 1,\\"#\,#\,!aa,aa 2,z1,aa 3,z1,aa
說明:果然,現在的“,”前面加上了轉義字元“\”。而剛才的引用符“””卻沒有被轉義,因為它已經沒有什麼歧義,不需要被轉義
注意:SELECT…INTO OUTFILE...產生的輸出檔案如果在目標目錄下有重名檔案,將不會建立成功,原始檔不能被自動覆蓋
方法 2:用 mysqldump 匯出資料為文字。
mysqldump –u username –T target_dir dbname tablename [option]
其中 option 引數可以是以下選項:
1) --fields-terminated-by=name(欄位分隔符);
2) --fields-enclosed-by=name 欄位引用符,比如每個欄位用雙引號括起來;
3) --fields-optionally-enclosed-by=name(欄位引用符,只用在 char、varchar 和 text 等字元型欄位上
4) --fields-escaped-by=name(轉義字元);
5) --lines-terminated-by=name(記錄結束符)。
常用引數 --compact :使得輸出結果簡潔,不包括預設選項中的各種註釋,例如例中對 test 資料庫中的表 emp 進行簡潔匯出 mysqldump -uroot -p --compact test emp >a
-F --flush-logs(備份前重新整理日誌):加上此選項後,備份前將關閉舊日誌,生成新日誌。使得進行恢復的時候直接從新日誌開始進行重做,大大方便了恢復過程
-l --lock-tables(給所有表加讀鎖):可以在備份期間使用,使得資料無法被更新,從而使備份的資料保持一致性,可以配合-F選項一起使用。
注意:
MyISAM 儲存引擎在備份的時候需要加上-l 引數,表示將所有表加上讀鎖,在備份期間,所有表將只能讀而不能進行資料更新。
但是對於事務儲存引擎(InnoDB 和 BDB)來說,可以採用更好的選項--single-transaction,此選項將使得 InnoDB 儲存引擎得到一個快照(Snapshot),使得備份的資料能夠保證一致性
例子,採用 mysqldump 生成指定分隔符分隔的文字:
mysqldump -uroot -T /tmp test emp --fields-terminated-by ',' --fields-optionally-enclosed-by '"'
輸出結果如下
more /tmp/emp.txt
1,"\\\"#,#,!aa","aa"
2,"z1","aa"
3,"z1","aa"
注意:
1)ubuntu測試中會出錯,解決方法如下。將輸出目錄改為/var/lib/mysql-files/. 例子中test是庫名,emp是表名,如果不寫則備份全部表
mysql> mysql> select * from person into outfile '/tmp/x.txt' fields terminated by ","; ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement mysql> show global variables like "%secure%"; +--------------------------+-----------------------+ | Variable_name | Value | +--------------------------+-----------------------+ | require_secure_transport | OFF | | secure_auth | ON | | secure_file_priv | /var/lib/mysql-files/ | +--------------------------+-----------------------+
2)如果非要用/tmp,則需要做如下操作 (測試了下又不行了...)
在/etc/apparmor.d/usr.sbin.mysqld檔案中加入一行程式碼如下 /data/export/** rw, 儲存退出後 /etc/init.d/apparmor reload #重新載入配置 再次匯出即可。
三. 匯入純文字資料
這裡只討論用 SELECT… INTO OUTFILE 或者 mysqldump 匯出的純資料文字的匯入方法。和匯出類似,匯入也有兩種不同的方法,分別是 LOAD DATA INFILE…和mysqlimport,它們的本質是一樣的,區別只是在於一個在 MySQL 內部執行,另一個在 MySQL 外部執行。
需要注意的是在匯入純文字資料之前,需要事先建立好表結構
1. 一個簡單的完整例子
首先準備表結構和文字資料,新建test庫:create database test,然後在test下新建表person
create table person( id int not null auto_increment, name varchar(40) not null, city varchar(20), salary int, primary key(id) ) engine=innodb default charset=utf8;
張三 北京 3000 李四 杭州 4000 王五 /N 4500 小明 天津 /N
每一項之間用Tab鍵進行分隔,如果該欄位為NULL,則用/N表示。
進入mysql並且切換到對應的庫後,執行下面命令匯入資料:
load data local infile "/var/lib/mysql/test/data.txt" into table person(name,city,salary);
注意
1. data.txt存放的位置,其他地方會報錯
2. 在mysql配置檔案中修改字元編碼
mysql 5.6 sudo vim /etc/mysql/my.cnf,重啟mysql來完成字符集的設定。新增以下兩行 (如果是上傳安裝包,vim /etc/my.cnf) [mysqld] character_set_server=utf8 binlog_format=row mysql 5.7 可能需要在etc/mysql/mysql.conf.d/mysqld.cnf中額外增加如下程式碼,有時候也不需要 [client] default-character-set=utf8
2. 使用“LOAD DATA INFILE…”命令匯入資料詳解
mysql > LOAD DATA [LOCAL] INFILE ‘filename’ INTO TABLE tablename [option]
option 可以是以下選項:
1. FIELDS TERMINATED BY 'string'(欄位分隔符,預設為製表符'\t');
2. FIELDS [OPTIONALLY] ENCLOSED BY 'char' 欄位引用符,如果加 OPTIONALLY 選項則只會做用在char, varchar和text等字元型欄位上,其他型別欄位預設不使用引用符
3. FIELDS ESCAPED BY 'char'(轉義字元,預設為'\');
4. LINES STARTING BY 'string'(每行前都加此字串,預設'');
5. LINES TERMINATED BY 'string'(行結束符,預設為'\n');
6. IGNORE number LINES(忽略輸入檔案中的前 n 行資料);
7. (col_name_or_user_var,...) (按照列出的欄位順序和欄位數量載入資料);
8. SET col_name = expr,... 將列做一定的數值轉換後再載入。
注意:
1. 其中 char 表示此符號只能是單個字元,string 表示可以是字串。
2. FILELD 和 LINES 和前面 SELECT …INTO OUTFILE…的含義完全相同,不同的是多了幾個不同的選項
例子1:將檔案“/tmp/emp.txt”中的資料載入到表 emp 中
mysql> load data infile '/tmp/emp.txt' into table emp fields terminated by ',' enclosed by'"' ;
例子2:如果不希望載入檔案中的前2行,加上ignore欄位
mysql> load data infile '/tmp/emp.txt' into table emp fields terminated by ',' enclosed by '"' ignore 2 lines;
例子3:如果發現檔案中的列順序和表中的列順序不符,或者只想載入部分列,可以在命令列中加上列的順序
mysql> load data infile '/tmp/emp.txt' into table emp fields terminated by ',' enclosed by '"' ignore 2 lines (id,content,name);
如果只想載入第一列,欄位的列表裡面可以只加第一列的名稱:
mysql> load data infile '/tmp/emp.txt' into table emp fields terminated by ',' enclosed by '"' ignore 2 lines (id);
例子4:如果希望將 id 列的內容+10 後再載入到表中,可以如下操作:
mysql> load data infile '/tmp/emp.txt' into table emp fields terminated by ',' enclosed by '"' set id=id+10;
3. 用 mysqlimport 來實現匯入資料詳解,具體命令如下
shell>mysqlimport –u root –p*** [--LOCAL] dbname order_tab.txt [option]
其中 option 引數可以是以下選項:
1. --fields-terminated-by=name(欄位分隔符);
2. --fields-enclosed-by=name(欄位引用符);
3. --fields-optionally-enclosed-by=name(欄位引用符,只用在 char、varchar 和 text 等字元型欄位上
4. --fields-escaped-by=name(轉義字元);
5. --lines-terminated-by=name(記錄結束符);
6. -- ignore-lines=number(或略前幾行)。
這與 mysqldump 的選項幾乎完全相同,這裡不再詳細介紹,簡單來看一個例子:
mysqlimport -uroot test /tmp/emp.txt --fields-terminated-by=',' --fields-enclosed-by='"'
轉載出處:https://www.cnblogs.com/regit/p/8041762.html