LOAD DATA INFILE 導入數(shù)據(jù)

標簽(空格分隔): mysql


LOAD DATA INFILE語句用于高速地從一個文本文件中讀取行,并寫入一個表中。文件名稱必須為一個文字字符串。
LOAD DATA INFILE 是 SELECT ... INTO OUTFILE 的相對語句。把表的數(shù)據(jù)備份到文件使用SELECT ... INTO OUTFILE,從備份文件恢復表數(shù)據(jù),使用 LOAD DATA INFILE。

1 語法

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char' ]
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number LINES]
    [(col_name_or_user_var,...)]
    [SET col_name = expr,...)]

標準示例

LOAD DATA LOCAL INFILE 'data.txt' INTO TABLE tbl_name 
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '"' 
LINES TERMINATED BY '\n'

只載入一個表的部分列

LOAD DATA LOCAL INFILE 'persondata.txt' INTO TABLE persondata (col1,col2)

2 LOW_PRIORITY | CONCURRENT 關鍵字

2.1 LOW_PRIORITY

該參數(shù)適用于表鎖存儲引擎,比如MyISAM, MEMORY, 和 MERGE,在寫入過程中如果有客戶端程序讀表,寫入將會延后,直至沒有任何客戶端程序讀表再繼續(xù)寫入。

2.2 CONCURRENT

使用該參數(shù),允許在寫入過程中其它客戶端程序讀取表內容。

3 L0CAL關鍵字

L0CAL關鍵字影響數(shù)據(jù)文件定位和錯誤處理。只有當 mysql-server 和 mysql-client 同時在配置中指定允許使用,L0CAL關鍵字才會生效。如果 mysqld 的 local_infile系統(tǒng)變量設置為 disabled,L0CAL關鍵字將不會生效。詳見Section 6.1.6, “Security Issues with LOAD DATA LOCAL”.

L0CAL關鍵字影響在哪里找到數(shù)據(jù)文件:

3.1 LOCAL load operations

如果指定了LOCAL,數(shù)據(jù)文將被客戶端程序從客戶端主機讀取,然后發(fā)送給服務器主機。文件路徑可以使用絕對路徑或相對路徑。如果使用相對路徑,數(shù)據(jù)文件實際路徑相對于客戶端程序啟動時的當前路徑。

使用LOCAL,將在服務器主機的臨時目錄創(chuàng)建一個數(shù)據(jù)文件的副本(linux 使用 /tmp,windows 使用 C:\WINDOWS\TEMP),如果臨時目錄剩余空間不足,將導致語句執(zhí)行失敗。

3.2 Non-LOCAL load operations

如果沒有指定LOCAL,數(shù)據(jù)五年間必須位于服務器值機上,直接由 mysql-server 讀取。mysql-serve 使用如下規(guī)則來定位文件:

1. 數(shù)據(jù)文件使用絕對路徑,直接使用

2. 數(shù)據(jù)文件使用相對路徑并且有前導的部分,將相對于 mysql-server 的數(shù)據(jù)目錄查找,例如 ./myfile.txt

3. 數(shù)據(jù)文件使用相對路徑并且沒有前導的部分,將相對于默認數(shù)據(jù)庫的數(shù)據(jù)文件目錄查找,例如 myfile.txt

根據(jù)上面的規(guī)則,./myfile.txt 將被定位到 mysql-server 的 data directory,而 myfile.txt 將被定位到 default database 的 database directory。

如果 db1 時默認數(shù)據(jù)庫,則下面的語句將從 db1 的數(shù)據(jù)庫目錄讀取 data.txt,即使明確指定把數(shù)據(jù)裝載到 db2

LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;

Non-LOCAL load operations 從服務器主機上讀取數(shù)據(jù)文將。出于安全原因,這個操作需要文件權限。 如果secure_file_priv 系統(tǒng)變量的value 不為空,數(shù)據(jù)文件必須放在該變量指定的目錄。如果該變量為空,數(shù)據(jù)文件必須可讀。

使用LOCAL將比讓服務器直接存取文件慢些,因為文件的內容必須從客戶主機傳送到服務器主機。在另一方面,你不需要file權限裝載本地文件。

3.3 L0CAL關鍵字對錯誤處理的影響

  1. 使用 LOAD DATA INFILE,data-interpretation 和 duplicate-key 錯誤會終止操作
  2. 使用 LOAD DATA LOCAL INFILE,data-interpretation 和 duplicate-key 錯誤會發(fā)出警告,操作將繼續(xù)執(zhí)行。對于duplicate-key錯誤,效果和指定了 IGNORE 關鍵字一樣。

4 REPLACE | IGNORE 關鍵字

REPLACE和IGNORE關鍵詞控制對現(xiàn)有的唯一鍵記錄的重復的處理。如果你指定REPLACE,新行將代替有相同的唯一鍵值的現(xiàn)有行。如果你指定IGNORE,跳過有唯一鍵的現(xiàn)有行的重復行的輸入。如果你不指定任何一個選項,當找到重復鍵鍵時,出現(xiàn)一個錯誤,并且文本文件的余下部分被忽略時。

5 FIELDS 子句

5.1 基本用法

如果你指定一個FIELDS子句,它的每一個子句(TERMINATED BY, [OPTIONALLY] ENCLOSED BY和ESCAPED BY)也是可選的,但是你必須至少指定一個。

如果你不指定 FIELDS 或 LINES ,缺省值為:

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n' STARTING BY ''

換句話說,缺省值導致讀取輸入時,LOAD DATA INFILE表現(xiàn)如下:

  1. 在 \n 處尋找行邊界
  2. 在 \t 處將行分進字段
  3. 不要期望字段由任何引號字符封裝
  4. 將由“\”開頭的定位符、換行符或“\”解釋成轉義序列。例如 \t, \n, and \ 分別解釋成 定位符,換行,反斜杠。

相反,缺省值導致在寫入輸出時,SELECT ... INTO OUTFILE表現(xiàn)如下:

  1. 在字段之間寫 \t
    2 .不用任何引號字符封裝字段
  2. 使用“\”轉義出現(xiàn)在字段中的 定位符、換行符或“\”字符
  3. 在行尾處寫換行符

5.2 FIELDS [OPTIONALLY] ENCLOSED BY

FIELDS [OPTIONALLY] ENCLOSED BY 控制哪些字段應該包裹在引號里面。

對于SELECT ... INTO OUTFILE 輸出,如果不包含OPTIONALLY選項,所有的字段將會被ENCLOSED BY指定的字符包裹,例如:

"1","a string","100.20"  
"2","a string containing a , comma","102.20"  
"3","a string containing a \" quote","102.20"  
"4","a string containing a \", quote and comma","102.20"  

如果我們指定OPTIONALLY,只有string數(shù)據(jù)類型(如 CHAR, BINARY, TEXT, 或 ENUM)的字段才會被ENCLOSED BY指定的字符包裹,例如:

1,"a string",100.20  
2,"a string containing a , comma",102.20  
3,"a string containing a \" quote",102.20  
4,"a string containing a \", quote and comma",102.20  

注意,如果在字段值內出現(xiàn)ENCLOSED BY字符,則通過使用ESCAPED BY字符作為前綴,對ENCLOSED BY字符進行轉義。另外,要注意,如果指定了一個空ESCAPED BY值,則可能會生成不能被LOAD DATAINFILE 正確讀取的輸出值。例如:

1,"a string",100.20  
2,"a string containing a , comma",102.20  
3,"a string containing a " quote",102.20  
4,"a string containing a ", quote and comma",102.20 

5.3 FIELDS ESCAPED BY

用來控制如何對特殊字符進行讀寫,如上面一個例子,導出和導入時指定FIELDS ESCAPED BY為雙引號["]才能被正確的導入,導出的格式如下,對字段內的雙引號["]進行了轉義。


    1,"a string",100.20  
    2,"a string containing a , comma",102.20  
    3,"a string containing a #" quote",102.20  
    4,"a string containing a #", quote and comma",102.20  

對于輸入:
假如FIELDS ESCAPED BY指定字符非空,則輸入時該字符被移除,后續(xù)的內容被添加到字段里。一些兩個字符的字符串序列且第一個字符是轉義字符的例外 。這些字符序列見下表。

Character| Escape Sequence

-------|----------
\0 | An ASCII NUL (X'00') character
\b | A backspace character
\n | A newline (linefeed) character
\r | A carriage return character
\t | A tab character.
\Z | ASCII 26 (Control+Z)
\N | NULL

假如FIELDS ESCAPED BY指定字符為空,將不會發(fā)生轉義序列的解釋。

對于輸出:
如果FIELDS ESCAPED BY指定字符非空,字符作為以下輸出的前綴。
1. FIELDS ESCAPED BY 字符,例如 \
2. FIELDS [OPTIONALLY] ENCLOSED BY 字符,例如 "
3. FIELDS TERMINATED BY and LINES TERMINATED BY 的 value 的第一個字符,例如\n
4. ASCII 0

如果LINES TERMINATED BY是空字符串,F(xiàn)IELDS TERMINATED BY非空,字符將不會被轉義,NULL 將輸出為 NULL而不是 \N。指定LINES TERMINATED BY為空字符串并不是個好主意,特別當內容中包含上表列出的特殊字符時。

5.4 LINES STARTING BY

如果所有希望讀入的行都含有一個我們希望忽略的共用前綴,則可以使用 LINES STARTING BY 'prefix_string' 來跳過前綴(以及該前綴前的所有字符)。如果某行不包括前綴,則整個行被跳過。
例如:

 
 LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test 
    FIELDS TERMINATED BY ','  LINES STARTING BY 'xxx';
  

假如/tmp/test.txt文件內容如下

xxx"abc",1  
something xxx"def",2  
"ghi",3  

則我們讀入的內容包括("abc",1) 和 ("def",2),第三行直接被跳過。

IGNORE number LINES

該選項可以被用于在文件的開始處忽略行。例如,我們可以使用IGNORE 1 LINES來跳過一個包含列名稱的起始標題行。

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;

5.5 在特定情況下,field-和line-handling選項相互影響

  1. 如果LINES TERMINATED BY是空字符串,F(xiàn)IELDS TERMINATED BY非空,行以FIELDS TERMINATED BY指定的字符串作為結尾。

  2. 如果FIELDS TERMINATED BY 與 FIELDS ENCLOSED BY值均為空(''),將使用固定行(無分割)格式。使用固定行格式,字段之間將沒有分隔符(行終止符依然可使用),列字段數(shù)據(jù)的讀取和寫入均按照字段定義的寬度去操作,如 TINYINT, SMALLINT, MEDIUMINT, INT, 和 BIGINT, 字段寬度分別為4, 6, 8, 11, 和 20。

5.5 不適合使用 LOAD DATA INFILE 的情況

1. 使用固定行格式(即FIELDS TERMINATED BY 和 FIELDS ENCLOSED BY 均為空),列字段類型為BLOB或TEXT。
2. 指定分隔符與其它選項前綴一樣,LOAD DATA INFILE不能對輸入做正確的解釋。例如:
    FIELDS TERMINATED BY '"' ENCLOSED BY '"'  
3. 如果 FIELDS ESCAPED BY 為空,字段值包含 FIELDS ENCLOSED BY 指定字符,或者 LINES TERMINATED BY 的字符在 FIELDS TERMINATED BY 之前,都會導致過早的停止 LOAD DATA INFILE操作。因為LOAD DATA INFILE不能準確的確定行或列的結束。

6 IGNORE number LINES 選項

IGNORE number LINES選項可以被用于在文件的開始處忽略行。
您可以使用IGNORE 1 LINES來跳過一個包含列名稱的起始標題行:

LOAD DATA INFILE '/tmp/test.txt'  INTO TABLE test IGNORE 1 LINES;

7 選擇導入的列

下面的語句會導入文件的所有列

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;

如果我們想導入表的某些列,需要指定列的列表

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);

如果輸入文件與表的列順序不同,我們必須指定一個列清單,否則mysql不能把輸入文件的字段與表的列匹配起來。

 mysql> LOAD DATA INFILE '/tmp/loadtest.txt' INTO TABLE loadtest 
    FIELDS TERMINATED BY ',' 
    OPTIONALLY ENCLOSED BY '"' 
    ESCAPED BY '#' 
    LINES TERMINATED BY '\n' 
    (c1, c2, c4, c3);  

列的清單可以包含列名或者用戶變量,在寫入列前我們需要使用SET語句對用戶變量進行轉換。對set語句及用戶變量有如下使用方法:

方法1:在用戶變量用于第一列之前,先把第一列的值賦予用戶變量,進行除法操作后輸入到c1。

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, @var1)
  SET column2 = @var1/100;

方法2The SET clause can be used to supply values not derived from the input file. 。使用下面例子把c3列設為當前時間

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, column2)
  SET column3 = CURRENT_TIMESTAMP;

方法3:把輸入賦予用戶變量,而不把用戶變量賦予表中的列,來丟棄此輸入值。

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, @dummy, column2, @dummy, column3);

7 通過管道導入數(shù)據(jù):

在unix系統(tǒng)中,如果我們想要從管道(pipe)中l(wèi)oad data,需要用如下方法:
[root@localhost tmp]# mkfifo /tmp/ls.dat  
[root@localhost tmp]# chmod 666 /tmp/ls.dat  
[root@localhost tmp]# find / -ls > /tmp/ls.dat &  
[root@localhost tmp]# mysql -e "LOAD DATA INFILE '/tmp/ls.dat' INTO TABLE test.tb1 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '#' LINES TERMINATED BY '\n'"  

注意:sql-mode使用嚴格事物模式STRICT_TRANS_TABLES會報錯

在另一窗口將數(shù)據(jù)寫入管道

[root@localhost /]# cat /tmp/loadtest.txt > /tmp/ls.dat  

注:可以先讀或者先寫管道,誰先誰后都可以,在寫入管道的數(shù)據(jù)被全部讀出前,處于阻塞狀態(tài)。

參考
LOAD DATA INFILE Syntax
mysql導入數(shù)據(jù)load data infile用法

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容