0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【MySQL】データベース内の全テーブル構造を維持したままデータだけを削除

0
Last updated at Posted at 2026-02-06

開発環境やテスト環境でデータベースをリセットしたいとき、「テーブル構造は残したまま、データだけを削除したい」というケースがあります。

DROP DATABASEしてしまうとマイグレーションを再実行する必要がありますが、TRUNCATE TABLEならテーブル構造を維持したままデータだけを削除できます。

本記事では、MySQLデータベース内の全テーブルを動的に取得し、一括でTRUNCATEするシェルスクリプトの実装方法を紹介します。

DELETEとは

DELETE は、テーブルの行を削除する DML ステートメントです。

テーブル内のデータの行を指定して削除することができます。
WHERE句を使って条件を絞ることも、全レコードを削除することも可能です。

-- 全レコードを削除
DELETE FROM users;

-- 条件を指定して削除
DELETE FROM users WHERE id = 10;

TRUNCATE TABLEとは

TRUNCATE TABLEは条件指定など行わず、テーブル内のデータを全て削除します。

ただ削除するだけならDELETEを使えばいいのでは?と思うかもしれませんが、TRUNCATE TABLEには大きな利点があります。

切り捨て操作はテーブルを削除して再作成するため、特に大きなテーブルの場合は、行を 1 つずつ削除するよりはるかに高速です。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.1.37 TRUNCATE TABLE ステートメント

全データを削除する際にはTRUNCATE TABLEが推奨されています。

DELETEとTRUNCATEの違い

操作 速度 AUTO_INCREMENT ロールバック WHERE句
DELETE 低速 維持される 可能 使用可能
TRUNCATE 高速 リセットされる 不可 使用不可

注意点:ロールバックできない

切り捨て操作は暗黙的なコミットを発生させるため、ロールバックできません。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.1.37 TRUNCATE TABLE ステートメント

本番環境で間違えてコマンドを叩いてデータを削除したら…と考えるだけで恐ろしいですね。

実装のポイント

1. INFORMATION_SCHEMAからテーブル一覧を取得

MySQLのINFORMATION_SCHEMA.TABLESを使用して、指定したデータベース内の全テーブルを動的に取得します。

SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA='your_database' 
  AND TABLE_TYPE='BASE TABLE';

TABLE_TYPE='BASE TABLE'を指定することで、ビューを除外しています。

2. 外部キー制約の一時無効化

テーブル間に外部キー制約がある場合、参照先のテーブルを先にTRUNCATEしようとするとエラーになります。
FOREIGN_KEY_CHECKSを一時的に無効化することで回避できます。

-- 無効化
SET FOREIGN_KEY_CHECKS=0;

-- TRUNCATEを実行...

-- 再有効化
SET FOREIGN_KEY_CHECKS=1;

3. データベースの存在チェック

存在しないデータベースに対して操作しようとするとエラーになるため、事前にチェックします。

SELECT SCHEMA_NAME 
FROM INFORMATION_SCHEMA.SCHEMATA 
WHERE SCHEMA_NAME='your_database';

完成版スクリプト

#!/bin/sh

set -e

# この辺りでDB接続のための環境変数をセットする

# 指定したDBの全テーブルをTRUNCATEする関数
truncate_all_tables() {
  DB_NAME=$1
  echo "Truncating all tables in $DB_NAME..."

  # データベースが存在するかチェック
  DB_EXISTS=$(mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -N -e "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='$DB_NAME';" 2>/dev/null)
  if [ -z "$DB_EXISTS" ]; then
    echo "  Database $DB_NAME does not exist, skipping..."
    return
  fi

  # 全テーブルを取得
  TABLES=$(mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -N -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='$DB_NAME' AND TABLE_TYPE='BASE TABLE';" 2>/dev/null)

  if [ -z "$TABLES" ]; then
    echo "  No tables found in $DB_NAME, skipping..."
    return
  fi

  # 外部キー制約の無効化とTRUNCATEを同一接続で実行
  SQL="SET FOREIGN_KEY_CHECKS=0;"
  for TABLE in $TABLES; do
    echo "  Truncating $DB_NAME.$TABLE..."
    SQL="${SQL} TRUNCATE TABLE \`$TABLE\`;"
  done
  SQL="${SQL} SET FOREIGN_KEY_CHECKS=1;"

  mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "$SQL" "$DB_NAME"

  echo "  Done truncating $DB_NAME"
}

# 使用例
truncate_all_tables "my_database"

mysqlコマンドのオプション解説

オプション 説明
-h ホスト名
-P ポート番号
-u ユーザー名
-p パスワード(オプションとパスワードの間にスペースを入れない)
-N カラムヘッダーを出力しない(スクリプトでの処理に便利)
-e SQLを直接実行

その他の注意点

本番環境での使用禁止

このスクリプトは開発・テスト環境専用です。本番環境では絶対に使用しないでください。

テーブル名のエスケープ

テーブル名にはバッククォート(`)を使用してエスケープしています。これにより、予約語や特殊文字を含むテーブル名にも対応できます。

mysql -e "TRUNCATE TABLE \`$TABLE\`;" "$DB_NAME"

権限

実行するユーザーには以下の権限が必要です:

  • SELECT on INFORMATION_SCHEMA
  • DROP on 対象データベース(TRUNCATEに必要)

応用:Dockerコンテナ化

このスクリプトをDockerイメージ化することで、CI/CDパイプラインやECSタスクから実行できます。

FROM alpine:3.19
RUN apk add --no-cache mysql-client
COPY scripts/truncate-db.sh /truncate-db.sh
RUN chmod +x /truncate-db.sh
ENTRYPOINT ["/truncate-db.sh"]

  • INFORMATION_SCHEMA.TABLESを使って動的にテーブル一覧を取得
  • FOREIGN_KEY_CHECKS=0で外部キー制約を一時無効化
  • -Nオプションでヘッダーなしの出力を取得し、シェルスクリプトで処理

この方法を使えば、テーブル構造を維持したままデータをリセットでき、マイグレーションを再実行する必要がありません。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?