在某些狀況下,爲了一些特定的目的,常常須要將表裏的數據導出爲某些符號分割的純數據文本,而不是 SQL 語句,由於LOAD DATA 的加載速度比普通的 SQL 加載要快 20 倍以上mysql
方法 1:使用 SELECT ...INTO OUTFILE ...命令來導出數據,具體語法以下。sql
mysql> SELECT * FROM tablename INTO OUTFILE 'target_file' [option];shell
其中 option 參數能夠是如下選項:數據庫
命令參數 | 說明 |
fields terminated by '字符' | 字段分隔符,默認字符爲製表符'\t' |
fields [optionally] enclosed by '單字符' | 字段引用符,加上optionally後在數字類型上不會有引用符號 |
fields escaped by '單字符' | 轉義字符,默認爲'\' |
lines starting by '字符' | 每行前都加此支付,默認爲空 |
lines terminated by '字符' | 行結束符,默認爲'\n' |
例子1,將 emp 表中數據導出爲數據文本,其中,字段分隔符爲「,」,每一個字段用雙引號引用起來,記錄結束符爲回車符(默認如此,能夠不寫)ubuntu
mysql> select * from emp into outfile '/tmp/emp.txt' fields terminated by "," enclosed by '"';vim
輸出結果以下app
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(記錄結束符)。
-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 外部執行。
須要注意的是在導入純文本數據以前,須要事先建立好表結構
首先準備表結構和文本數據,新建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
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;
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='"'