SQL INSERT文と一括挿入

単一行、複数行、INSERT SELECTのSQL INSERT構文を学びます。デフォルト値、自動採番、ON CONFLICTによるUPSERT、一括挿入戦略を解説します。

DML

詳細な説明

SQL INSERT文と一括挿入

INSERT 文はテーブルに新しい行を追加します。その各種バリエーションを理解することは、効率的なデータ読み込みとアプリケーション開発に不可欠です。

単一行の挿入

INSERT INTO employees (name, email, department, salary)
VALUES ('Alice Johnson', 'alice@example.com', 'Engineering', 95000);

常にカラム名を明示的に指定しましょう。カラムの順序に依存する書き方は脆弱で、テーブルスキーマが変更されると破綻します。

複数行の挿入

INSERT INTO products (name, price, category)
VALUES
  ('Widget A', 29.99, 'Gadgets'),
  ('Widget B', 39.99, 'Gadgets'),
  ('Widget C', 49.99, 'Gadgets');

複数行の挿入は個別のINSERT文より大幅に高速です。ラウンドトリップとトランザクションのオーバーヘッドが削減されるためです。

INSERT SELECT

あるテーブルやクエリから別のテーブルにデータをコピーします:

INSERT INTO archived_orders (order_id, customer_id, total, order_date)
SELECT order_id, customer_id, total, order_date
FROM orders
WHERE order_date < '2024-01-01';

Upsert(INSERT ON CONFLICT)

PostgreSQL:

INSERT INTO users (email, name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email)
DO UPDATE SET name = EXCLUDED.name;

MySQL:

INSERT INTO users (email, name)
VALUES ('alice@example.com', 'Alice')
ON DUPLICATE KEY UPDATE name = VALUES(name);

デフォルト値と自動採番

自動採番カラムやデフォルト値を持つカラムは省略できます:

INSERT INTO logs (message, level)
VALUES ('User logged in', 'INFO');

一括挿入のベストプラクティス

  • 中程度のバッチ(100~1000行)には複数行VALUESを使用する
  • 非常に大量のデータロードには、データベース固有の一括ツール(PostgreSQLの COPY、MySQLの LOAD DATA)を使用する
  • 一括ロード中はインデックスと制約を一時的に無効化し、完了後に再構築する
  • 大量の挿入はアトミック性とパフォーマンスのために明示的なトランザクションで囲む

INSERTは最も頻繁に使用されるDML操作の1つであり、そのバリエーションをマスターすることは効率的なデータパイプラインの構築に不可欠です。

ユースケース

データインポートパイプラインがCSVアップロードを処理し、ON CONFLICT処理で既存エントリの更新と新規エントリの挿入をシームレスに行いながら、数千件のレコードをバッチ挿入する場面。

Try It — SQL Formatter

フルツールを開く