LoginSignup
1
2

More than 5 years have passed since last update.

CSVファイルを丸ごと挿れたい(間違わないLOAD DATA INFILE)

Last updated at Posted at 2019-05-20

はじめに

CSVファイルを1件1件取り出して、加工してSQLを生成……
なんてことを、これまでしてきました。
もちろんすごく遅いです。

LOAD DATA INFILEを使うことでファイルインポートができます。
とはいえ、ざっくり調べても「あまり使えなさそう?」と思っていた私がいます。
ですが理解してみると一転して、様々なCSV案件で大活躍です。
未来の私のために今日もメモします。

LOAD DATA INFILEとは
LOAD DATA INFILE ステートメントは、非常に高速にテキストファイルからテーブルに行を読み取ります。

参考URL

理解のポイント(下記構文を見ながら)

  • CSVファイルを読み込み、INSERTを行うイメージです。
  • CSVの1列目(例:A1,B1など)が、users.idカラムに入ります。
  • CSVの2列目(例:A2,B2など)が、users.nameカラムに入ります。
    • つまりカラムとCSVの順番は、バラバラでも対応が可能ということです
  • SET以降は「CSVにはないけれどカラムに入れたい値」をセットすることができます。
    • もはやCSVデータとはほぼ関係なく、SQL側のための機能です

構文

LOAD DATA INFILE 'nzn.csv'
  INTO TABLE `users`
  FIELDS TERMINATED BY ','
  ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES
  (
     `id`
      , `name`
      , `price`
  ) SET
     `created_at` = TIMESTAMP

各行の理解

  • FIELDS TERMINATED : CSVの区切り文字を指します。ほぼ必須です。
  • ENCLOSED BY '"' : 文字列などはダブルクォーテーションで囲われていますが、良きように消してINSERTをしてくれます。ほぼ必須です。
  • LINES TERMINATED BY '\r\n' : 改行コードの認識を定義します。
    • csvファイルがCRLFなのに\nと指定すると、1行しか入らないなど不都合が起きます。
  • IGNORE 1 LINES : CSVには見出しがつきもの。プログラム側で削除するより高速なのでLOAD DATA側で除外すると少し幸せになります。

ではbashから呼び出してみよう

readonly ENC='\"'; #エスケープ
$code="
LOAD DATA INFILE 'nzn.csv'
  INTO TABLE users
  FIELDS TERMINATED BY ','
  ENCLOSED BY '${ENC}'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES
  (
     id
      , name
      , price
  ) SET
     created_at = TIMESTAMP
     updated_at = ${TIME_STAMP}
";

ちなみにbashで実行の場合、バッククォーツ自体に意味があるので、誤認されるみたいです。
テーブルやカラムにも、バッククォーツは付けずに記述しましゅ。

最後に

他にも変数の指定ができますが、これが初めて使うときに理解を遠ざける要因の1つでした。結局、私の案件の場合は変数は不要でしたので、上記のようなLOAD DATAで落ち着きました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2