【完全版】MySQL「ERROR 1146: Table doesn’t exist」の原因と対処法|テーブル不存在エラー全パターン徹底解説

【完全版】MySQL「ERROR 1146: Table doesn’t exist」の原因と対処法|テーブル不存在エラー全パターン徹底解説

MySQL/MariaDBにクエリを実行した時、以下のエラーで弾かれた経験はありませんか?

ERROR 1146 (42S02): Table 'mydb.users' doesn't exist
ERROR 1146 (42S02): Table 'mydb.Users' doesn't exist
PHP Fatal error: SQLSTATE[42S02]: Base table or view not found: 1146
java.sql.SQLSyntaxErrorException: Table 'mydb.users' doesn't exist

「テーブルが存在しません」というシンプルなメッセージですが、実際の原因は10種類以上あり、「テーブルは確かに存在するのにエラーが出る」ケースが頻発します。

  • SHOW TABLESで一覧表示されるのにアクセスできない
  • 開発環境では動くが本番では失敗する
  • MySQLサーバーを移行した後から発生する
  • Dockerコンテナを再起動したらテーブルが消えた
  • 大文字小文字を変えただけで動く時がある
  • レプリケーション環境で時々起きる
  • InnoDB復旧後にいくつかのテーブルだけ消失

本記事では、MySQL ERROR 1146 のすべての原因と対処法を、現場で即使えるトラブルシューティング手順として整理します。テーブル名のスペル問題から、データベース選択ミス、lower_case_table_names設定、InnoDB ファイル消失、Docker・AWS RDS対応、復旧手順、プログラム言語別対処、FAQまで完全網羅。この1本でMySQLのテーブル不存在エラーが全て解決します。


目次

結論:今すぐ試すべき3ステップ

時間がない方向けに、まず試すべき手順を示します。

ステップ1:テーブルが本当に存在するか確認

-- 接続中のDBで全テーブル確認
SHOW TABLES;

-- 該当テーブルの存在確認(INFORMATION_SCHEMA経由)
SELECT TABLE_SCHEMA, TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME = 'users';

ステップ2:データベース指定を確認

-- 現在選択中のDB
SELECT DATABASE();

-- 別DBに切り替えてみる
USE mydb;
SELECT * FROM users LIMIT 1;

ステップ3:大文字小文字を確認

-- テーブル名の大文字小文字を表示
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 
WHERE LOWER(TABLE_NAME) = LOWER('users');

それでも解決しない場合は、以下の詳細な原因分析へ進んでください。


まず押さえる:エラーメッセージの読み解き方

ERROR 1146 (42S02): Table 'mydb.users' doesn't exist
                          ↑     ↑
                       DB名    テーブル名

エラーから読み取れる情報:

  • DB名: mydb
  • テーブル名: users
  • SQLSTATE: 42S02(テーブル/ビュー未発見の標準コード)

このエラーは「指定されたDB名.テーブル名の組み合わせが見つからない」ことを意味します。

「見つからない」が意味する可能性

状況実態
テーブルが本当に存在しない削除済み、未作成
DB名が違う別のDBに作成済み
テーブル名のスペルミスタイポ
大文字小文字の不一致OS設定依存
ファイルレベルで壊れているInnoDB .ibd 不整合
権限がない※MySQLは権限がない場合も1146を返すことがある

ERROR 1146の原因カテゴリ

カテゴリ頻度
スペル・参照ミステーブル名タイプミス、DB指定漏れ最多
大文字小文字系lower_case_table_names設定、OS依存
DB選択系USE文の漏れ、デフォルトDB違い
削除・移行系DROP実行済み、移行不備
InnoDB ファイル系.ibd消失、innodb_file_per_table関連
ビュー・パーティション系ビュー定義壊れ、パーティション欠損
権限系テーブルの権限がないため1146扱い
環境固有Docker volume、レプリケーション

これらを順番にチェックします。


【原因①】テーブル名・データベース名の指定ミス(最頻出)

最も多いケースです。

スペルミス・タイポ

-- ❌ 間違ったテーブル名
SELECT * FROM userss;
SELECT * FROM Users;     -- 環境によっては失敗

-- ✅ 正しいテーブル名(実際の名前と完全一致)
SELECT * FROM users;

データベース指定漏れ

接続中のDBが異なる場合に発生:

-- 現在のDB
SELECT DATABASE();
-- 結果: testdb(なのに users は mydb にある)

-- ❌ 失敗
SELECT * FROM users;

-- ✅ DB名で修飾
SELECT * FROM mydb.users;

-- ✅ USE で切り替え
USE mydb;
SELECT * FROM users;

接続後のデフォルトDB確認

SELECT DATABASE();  -- 現在のDB
SHOW DATABASES;     -- 全DB一覧

全DBからテーブルを検索

SELECT TABLE_SCHEMA, TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '%users%';

これでどのDBにあるか一目で分かります。


【原因②】大文字小文字問題(最大の落とし穴)

MySQLはOSによってテーブル名の扱いが異なるため、開発・本番で挙動が変わります。

lower_case_table_names 設定

SHOW VARIABLES LIKE 'lower_case_table_names';
動作
0テーブル名は作成時のまま保存・大文字小文字を区別
1テーブル名は全て小文字で保存・大文字小文字を区別しない
2作成時のまま保存・比較時は小文字化(macOS等)

OSごとのデフォルト値

OSデフォルト値
Linux0(区別する)
Windows1(区別しない)
macOS2(保存はそのまま、比較時は無視)

問題発生パターン

開発(Mac、値=2): CREATE TABLE Users → 大小文字無視で動作
本番(Linux、値=0): SELECT * FROM users → ERROR 1146("Users" として作られているため)

確認方法

-- 実際のテーブル名(大文字小文字含む)
SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA = 'mydb'
ORDER BY TABLE_NAME;

対処法1:適切なテーブル名でアクセス

-- 実際に保存されている名前で指定
SELECT * FROM `Users`;     -- バッククォートで囲むと確実

対処法2:lower_case_table_names を統一

⚠️ この設定は MySQL初期化時にのみ変更可能 で、運用中の変更は推奨されません。

# /etc/mysql/my.cnf

[mysqld]

lower_case_table_names = 1

設定変更にはデータベースを完全クリーンインストールするか、慎重なデータ移行手順が必要です。

対処法3:開発時から統一規約を採用

業務開発では「全テーブル名を小文字」「スネークケース」のような命名規約を設けて、OS依存の問題を回避するのがベストプラクティスです。

-- 推奨
CREATE TABLE users (...);
CREATE TABLE user_profiles (...);

-- 非推奨
CREATE TABLE Users (...);
CREATE TABLE UserProfiles (...);

【原因③】テーブルが削除されている

DROPされたか、データファイルが消失している可能性です。

削除履歴の確認

MySQLは標準では削除履歴を残しません。Binary Log(バイナリログ)が有効なら確認できます:

-- バイナリログの状態
SHOW VARIABLES LIKE 'log_bin';

-- 有効な場合、ログを確認
SHOW BINARY LOGS;

-- 特定ログからDROP文を検索
SHOW BINLOG EVENTS IN 'mysql-bin.000123';
# binログをテキストで読む
mysqlbinlog /var/log/mysql/mysql-bin.000123 | grep -i "DROP TABLE"

一般ログの確認

-- 一般ログ有効化(事前設定が必要)
SHOW VARIABLES LIKE 'general_log%';

-- ログ確認
SELECT * FROM mysql.general_log 
WHERE argument LIKE '%DROP TABLE%users%' 
ORDER BY event_time DESC;

復旧手段

バックアップから復元

# mysqldump からの復元
mysql -u root -p mydb < backup_mydb.sql

# 特定テーブルだけ取り出す
grep -E "DROP TABLE.*users|CREATE TABLE.*users|INSERT INTO.*users" backup.sql > users.sql

Point-in-Time Recovery(PITR)

# バックアップ復元 + バイナリログ適用
mysql < backup.sql
mysqlbinlog --stop-datetime="2026-06-17 10:00:00" mysql-bin.000123 | mysql

バックアップがない場合の最終手段

InnoDB の ibdataibd ファイルから直接復旧する特殊技法もありますが、専門ツール(Percona Data Recovery Tool 等)の使用や有償サービスが必要です。


【原因④】InnoDB の .ibd ファイル消失・破損

InnoDB エンジンでは、innodb_file_per_table 設定時に各テーブルが個別の .ibd ファイルで管理されます。

設定確認

SHOW VARIABLES LIKE 'innodb_file_per_table';
-- ON: 個別ファイル / OFF: 共有 ibdata1

データファイルの場所確認

SHOW VARIABLES LIKE 'datadir';
-- 例: /var/lib/mysql/
# データディレクトリ内のファイル
ls -la /var/lib/mysql/mydb/
# 各テーブルの .ibd ファイルがあるはず
# users.ibd, products.ibd, ...

.frm ファイルだけ残っているケース

MySQL 5.7以前では、テーブル定義.frmとデータ.ibdが別ファイル。なんらかの理由で .ibd のみ消えると ERROR 1146 が出ます。

ls /var/lib/mysql/mydb/users.*
# users.frm(定義ファイル)はあるが
# users.ibd(データファイル)がない

.ibd ファイル再リンク(IMPORT TABLESPACE)

別の同じ構造のサーバーから .ibd を持ってきて復旧:

-- 1. テーブルを再作成
USE mydb;
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

-- 2. テーブルスペースを切り離す
ALTER TABLE users DISCARD TABLESPACE;

-- 3. 別環境からコピーした .ibd と .cfg を配置
-- /var/lib/mysql/mydb/ に コピー

-- 4. テーブルスペースをインポート
ALTER TABLE users IMPORT TABLESPACE;

⚠️ MySQL 8.0以降は .frm ファイルがなくなり、メタデータは mysql.ibd に統合されています。挙動が異なるので公式ドキュメント参照。

InnoDB 強制復旧モード

データファイルが破損している場合、強制復旧モードで起動して救出:

# /etc/mysql/my.cnf

[mysqld]

innodb_force_recovery = 1 # 1〜6、徐々に強い復旧

sudo systemctl restart mysql

復旧モードでmysqldump → 通常モードで再構築 が王道。値が大きいほどリスクが高まるので、必ず1から試してください。


【原因⑤】データディレクトリ移行・コピー失敗

サーバー移行時にデータディレクトリのコピー方法が不適切な場合に発生します。

安全な移行手順

# 1. MySQL停止
sudo systemctl stop mysql

# 2. データディレクトリを完全コピー(権限ごと)
sudo rsync -av /var/lib/mysql/ user@newhost:/var/lib/mysql/

# 3. 権限調整(新サーバー側で)
sudo chown -R mysql:mysql /var/lib/mysql

# 4. 起動
sudo systemctl start mysql

よくある失敗

# ❌ MySQL停止せずにコピー → データ整合性破損
cp -r /var/lib/mysql /backup/

# ❌ 一部ファイルだけコピー → InnoDB不整合
cp /var/lib/mysql/mydb/users.* /new/

# ❌ 権限を引き継いでいない → MySQLが読めない

不完全な移行後の症状

  • SHOW TABLES には表示される
  • でも SELECT * FROM table で 1146 エラー
  • MySQLログに「Tablespace open failed」などの警告

復旧

データディレクトリ移行に失敗した場合、最も確実なのは論理バックアップ(mysqldump)からの再構築です:

# 旧サーバーで論理バックアップ
mysqldump -u root -p --all-databases --routines --triggers --events > backup.sql

# 新サーバーで復元
mysql -u root -p < backup.sql

【原因⑥】ビュー(VIEW)が壊れている

ビューも INFORMATION_SCHEMA.TABLES に出ますが、参照先テーブルがなくなると 1146 を返します。

ビューの確認

-- ビュー一覧
SELECT TABLE_NAME, VIEW_DEFINITION 
FROM INFORMATION_SCHEMA.VIEWS 
WHERE TABLE_SCHEMA = 'mydb';

-- ビューの定義確認
SHOW CREATE VIEW user_summary;

ビューの再作成

参照先テーブルを復旧した後、ビューを再作成:

DROP VIEW IF EXISTS user_summary;
CREATE VIEW user_summary AS
SELECT id, name, email FROM users;

ビューの依存テーブル確認

SELECT TABLE_NAME, VIEW_DEFINITION 
FROM INFORMATION_SCHEMA.VIEWS 
WHERE VIEW_DEFINITION LIKE '%users%';

【原因⑦】パーティション関連

パーティション化されたテーブルで一部パーティションが消失したケースです。

パーティション確認

SELECT 
    PARTITION_NAME, 
    PARTITION_DESCRIPTION, 
    TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'mydb' 
  AND TABLE_NAME = 'orders';

パーティション分離されたファイル

ls /var/lib/mysql/mydb/orders*
# orders#P#p202601.ibd
# orders#P#p202602.ibd
# ...

一部の .ibd が消失すると、該当パーティションへのクエリで 1146 が出ます。

対処

パーティション単位での復旧は難易度が高いため、論理バックアップから再構築が基本対処です。


【原因⑧】Docker 環境での 1146

Docker MySQL コンテナ特有のシナリオがあります。

よくあるシナリオ

# 初回コンテナ作成
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=pass mysql:8.0

# CREATE TABLE を実行
mysql -h 127.0.0.1 -u root -p

# コンテナ削除(ボリュームなし)
docker rm -f mysql

# 再作成 → テーブルが消失
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=pass mysql:8.0
mysql> SELECT * FROM users;
-- ERROR 1146

原因

Dockerコンテナの /var/lib/mysql をホストにマウントしていない場合、コンテナ削除でデータも消失します。

対処:永続ボリュームの利用

# Named volume を使う
docker run -d \
    --name mysql \
    -e MYSQL_ROOT_PASSWORD=pass \
    -v mysql_data:/var/lib/mysql \
    mysql:8.0

docker-compose の場合

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: mydb
    volumes:
      - mysql_data:/var/lib/mysql      # ← 必須

volumes:
  mysql_data:

初期化スクリプトでテーブル作成

services:
  mysql:
    image: mysql:8.0
    volumes:
      - mysql_data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql   # 初期化SQL

init.sql:

CREATE DATABASE IF NOT EXISTS mydb;
USE mydb;
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100)
);

これでコンテナ初回作成時にテーブルが自動構築されます。

⚠️ 初期化スクリプトは既存ボリュームには適用されません。新規ボリュームのみ。

既存ボリュームを使い続けたい場合

# ボリュームから直接接続して状態確認
docker run -it --rm \
    -v mysql_data:/var/lib/mysql \
    mysql:8.0 ls /var/lib/mysql/mydb/

データが残っていれば、新コンテナでマウントすればOK。


【原因⑨】レプリケーション環境での同期遅延

レプリカ(スレーブ)側で 1146 エラーが出るケースがあります。

状況例

  • マスター側で CREATE TABLE 実行
  • アプリがレプリカに SELECT クエリ送信
  • レプリカへの同期が遅れていて、テーブルがまだない → ERROR 1146

確認

-- レプリカ側で
SHOW REPLICA STATUS\G
-- または旧構文
SHOW SLAVE STATUS\G
Seconds_Behind_Source: 5    -- 5秒遅延中
Last_Error: ...

対処

  • レプリケーション遅延の改善(ハードウェア・ネットワーク)
  • アプリ側でリトライロジック実装
  • 重要な直後の読み取りはマスター(プライマリ)に向ける
  • 読み書き分離フレームワークで遅延考慮

マスター/レプリカでテーブル定義不一致

-- 各サーバーでテーブル定義確認
SHOW CREATE TABLE users\G

不一致がある場合、DDLが片側だけ実行された可能性。マスター側で再実行が必要。


【原因⑩】権限不足が ERROR 1146 として返される

MySQL は仕様上、権限のないテーブルに対しても 1146 を返すことがあります。

確認

-- 自分の権限確認
SHOW GRANTS;

-- 特定テーブルへの権限
SHOW GRANTS FOR CURRENT_USER();

対処

-- 必要な権限を付与(root等で実行)
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.users TO 'app_user'@'%';
FLUSH PRIVILEGES;

権限関連の詳細はMySQL ERROR 1045 access denied の記事を参照してください。


AWS RDS / クラウドDB での 1146

AWS RDS for MySQL

よくある原因

  • スナップショットから復元時の不整合
  • パラメーターグループの lower_case_table_names 変更
  • マルチAZ切り替え時の一時的な不整合
  • リードレプリカでの遅延

対処

# RDSログ確認
aws rds describe-db-log-files --db-instance-identifier mydb
aws rds download-db-log-file-portion --db-instance-identifier mydb --log-file-name error/mysql-error.log

RDSは/var/lib/mysqlに直接アクセスできないため、SQLレベルでの確認と対処に限られます。

Google Cloud SQL

  • Cloud Logging で mysql-general ログ確認
  • スナップショットからの新規インスタンス起動でリストア

Azure Database for MySQL

  • Azure Portal → 該当MySQL → 監視 → メトリック
  • バックアップ復元機能で過去時点を復旧

プログラム言語別 ERROR 1146 対処

PHP(PDO)

try {
    $stmt = $pdo->query("SELECT * FROM users");
} catch (PDOException $e) {
    if ($e->getCode() === '42S02') {
        // ERROR 1146 - Table doesn't exist
        error_log("Table not found: " . $e->getMessage());
        // テーブル自動作成 or エラー応答
    }
}

Python(PyMySQL)

import pymysql

try:
    with conn.cursor() as cursor:
        cursor.execute("SELECT * FROM users")
except pymysql.err.ProgrammingError as e:
    if e.args[0] == 1146:
        print("テーブルが存在しません:", e)

Java(JDBC)

try (Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
    // ...
} catch (SQLException e) {
    if (e.getErrorCode() == 1146) {
        System.err.println("テーブル不存在: " + e.getMessage());
    }
}

Node.js(mysql2)

try {
    const [rows] = await conn.query('SELECT * FROM users');
} catch (err) {
    if (err.errno === 1146) {
        console.error('Table not found:', err.message);
    }
}

ORMでの自動マイグレーション

多くのORMは自動でテーブルを作成・更新できます:

# Django
python manage.py migrate

# SQLAlchemy
Base.metadata.create_all(engine)

# Sequelize
sequelize.sync()

ローカル開発で頻繁にスキーマ変更する場合、ORMのマイグレーション機能で自動化するのが安全です。


関連エラーと違い

ERROR 1049 (42000): Unknown database

DBそのものが存在しない場合:

USE nonexistent;
-- ERROR 1049 (42000): Unknown database 'nonexistent'

対処:

CREATE DATABASE nonexistent;

ERROR 1051 (42S02): Unknown table

DROP TABLE 等で存在しないテーブルを指定した場合:

DROP TABLE users;
-- 既にない場合: ERROR 1051

-- IF EXISTS で回避
DROP TABLE IF EXISTS users;

ERROR 1054 (42S22): Unknown column

が存在しない場合。テーブルはあるが列名がミスっている:

SELECT username FROM users;
-- 実際の列名は user_name の場合: ERROR 1054

ERROR 1064: SQL syntax error

SQL構文エラー。テーブル名と関係ない場合も多いですが、テーブル名にスペースや予約語を含むと出ることがあります:

-- ❌
SELECT * FROM order;

-- ✅
SELECT * FROM `order`;

予防策・ベストプラクティス

ERROR 1146 を起こさない設計と運用のポイント。

1. 命名規約の統一

  • 全テーブル名を小文字
  • 単語区切りはアンダースコア
  • 予約語の回避
-- 推奨
CREATE TABLE user_profiles (...);

-- 避ける
CREATE TABLE UserProfiles (...);  -- 大文字小文字でOS依存
CREATE TABLE order (...);          -- 予約語

2. 永続化の確認

Docker・仮想環境では、必ずボリュームマウントを設定:

volumes:
  - mysql_data:/var/lib/mysql

3. 定期バックアップ

# 毎日バックアップ
0 3 * * * mysqldump -u root --all-databases | gzip > /backup/mysql-$(date +\%Y\%m\%d).sql.gz

cron運用はcrontab記事参照。

4. データ移行は論理バックアップ経由

物理コピーは整合性リスクが高い:

# 推奨
mysqldump --all-databases > backup.sql
mysql < backup.sql

# 避けるべき(リスクあり)
rsync /var/lib/mysql/ newhost:/var/lib/mysql/

5. 監視

-- テーブル一覧を定期取得して比較
SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_ROWS, DATA_LENGTH
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');

定期的に実行し、行数の急激な変動や消失を検知。

6. lower_case_table_names を統一

各環境の MySQL 設定をインストール時から統一:

[mysqld]
lower_case_table_names = 1

開発・本番ともに同じ値で構築。

7. CI/CDでスキーマチェック

# CI で実行
mysqldump -d -u root mydb > schema_actual.sql
diff schema_expected.sql schema_actual.sql || exit 1

スキーマの意図しない変更を検知できます。


トラブルシューティング・チェックリスト

  1. エラーメッセージから DB.テーブル を確認
  2. SHOW TABLES でテーブル存在確認
  3. SELECT DATABASE() で接続DBを確認
  4. INFORMATION_SCHEMA.TABLES で全DB横断検索
  5. 大文字小文字を変えてみる、バッククォートで囲む
  6. lower_case_table_names 設定確認
  7. /var/lib/mysql/DB名/ のファイル存在確認(要root)
  8. 権限確認: SHOW GRANTS
  9. Docker環境なら volume 設定確認
  10. レプリケーション環境なら同期遅延確認
  11. バックアップから復元検討
  12. 最終手段:InnoDB 強制復旧モード

よくある質問(FAQ)

Q1. SHOW TABLES で表示されているのに SELECT で 1146 が出ます

考えられる原因:

  • バッククォートが必要な特殊名(大小文字混在、予約語、ハイフン等)
  • 権限がない(MySQLは権限なしでも 1146 を返すことがある)
  • 物理ファイル(.ibd)の破損
-- バッククォートで明示
SELECT * FROM `Users`;
SELECT * FROM mydb.`Users`;

Q2. 大文字小文字を意識せず使いたいです

lower_case_table_names = 1 を MySQL 初期化時 に設定。既存環境では:

  • 命名規約として全テーブルを小文字にする
  • アプリ側でバッククォート + 明示的なケース指定

Q3. テーブルを誤って DROP しました。復旧できますか?

  • バックアップがある → mysqldump から復元
  • Binary Log有効 → Point-in-Time Recovery
  • どちらもない → Percona Data Recovery Tool 等の専門手段
  • クラウドDB → スナップショット復元

普段から自動バックアップを設定しておくことが最重要です。

Q4. Dockerでテーブルが消えました

ボリュームマウントなしのコンテナを docker rm した可能性大。次回からは:

volumes:
  - mysql_data:/var/lib/mysql

を必ず設定してください。

Q5. MySQL を Linux→Windows に移行したら 1146 が大量発生します

lower_case_table_names のデフォルト値が異なるためです。移行先で 1 に設定してから論理バックアップ復元してください。

[mysqld]
lower_case_table_names = 1

⚠️ 既存データありでこの値を変更するのは危険。新規DBで設定してインポート。

Q6. INFORMATION_SCHEMA でテーブルは見えるのにクエリで 1146

メタデータ(INFORMATION_SCHEMA)と実データ(テーブルスペース)の不整合の可能性。InnoDB の .ibd ファイルが消失している場合があります:

ls /var/lib/mysql/mydb/
# users.ibd が存在しない、サイズが0など

復旧手段は限定的。バックアップからの再インポートが基本対処です。

Q7. .frm ファイルがあって .ibd がない場合は?

MySQL 5.7以前で発生するパターン。同じ構造のテーブルを別環境で作って .ibd をインポート:

CREATE TABLE users (...);  -- 同じ定義で作成
ALTER TABLE users DISCARD TABLESPACE;
-- .ibd ファイルをコピー
ALTER TABLE users IMPORT TABLESPACE;

Q8. テストデータベースでテーブル名が大文字になります

MySQL を Mac で動かしている場合、lower_case_table_names = 2 が原因の可能性。本番(Linux)と挙動が変わるので、開発・本番で命名規約を統一推奨。

Q9. CREATE TABLE 成功後すぐ SELECT で 1146

考えられる原因:

  • 異なる接続セッション、異なる DB に作成された
  • レプリカ側を見ている
  • トランザクション分離レベルの影響(実際は稀)
-- 作成直後に確認
SHOW TABLES LIKE 'users';
SELECT DATABASE();

Q10. Oracle ORA-00942 との違いは?

両者とも「テーブル/ビューが存在しない」エラーですが:

項目MySQL 1146Oracle ORA-00942
権限不足の挙動1146を返す可能性必ず ORA-00942
スキーマ参照DBで明示分離スキーマがユーザーと結合
大文字小文字OS依存引用符付きのみ区別

詳細はOracle ORA-00942の記事をご参照ください。

Q11. AWS RDS でテーブルが見えなくなりました

考えられる原因:

  • マスターからリードレプリカへ接続している(遅延)
  • スナップショット復元で前時点に戻った
  • パラメーターグループの設定変更

RDSコンソールから状態確認とログ取得。

Q12. Webアプリで時々 1146 が発生します

可能性:

  • 複数の DB を切り替える処理でミス
  • セッション間の DB 状態管理ミス
  • マスター/スレーブ振り分けでスレーブの遅延

アプリログとMySQLログ両方で発生時刻を突き合わせて原因特定。


参考リンク・関連資料

MySQL公式ドキュメント

MariaDB

復旧ツール

Docker

クラウドDB

関連エラー記事(本サイト)


まとめ

MySQL ERROR 1146 は単純なエラーに見えて、10種類以上の原因があります。要点を再整理します。

  • エラーから情報を読む: Table 'DB.テーブル' doesn't exist の構造を把握
  • 最頻出原因: スペル・大文字小文字(OS依存)、DB選択ミス
  • lower_case_table_names: Linux/Win/Mac でデフォルト値が違うので注意
  • InnoDB ファイル消失: .ibd ファイル確認、必要なら強制復旧モード
  • Docker環境: ボリュームマウント忘れで頻発
  • AWS RDS: スナップショット復元 / マスターレプリカ確認
  • 予防: 命名規約・永続化・バックアップ・移行手順の標準化

これらの知識は、Webアプリ開発・DB管理・本番運用・移行作業・障害復旧など、MySQL を扱うあらゆる場面で必須です。本記事をブックマークしておけば、ERROR 1146 に遭遇した時の対応が大幅に効率化されます。


本記事は2026年6月時点の情報をもとに、MySQL 5.7 / 8.0 / 8.4 および MariaDB 10.x / 11.x での動作確認・公式ドキュメントに基づき作成しています。バージョンによって挙動が異なる場合があるため、最新の情報はMySQL公式ドキュメントもあわせてご確認ください。