topic: db (PDO / SQL / マルチDB) / ch11 — MySQL 固有の文法と運用 / 演習 03

📝 ドリル 03 — TRUNCATE と DELETE の挙動を比較する

問題

採点ランナーが items テーブルに 3 件のレコードを用意する。

  1. SELECT COUNT(*) FROM items で件数を取得し、before: {N} を出力
  2. 全件削除する
    • MySQL なら TRUNCATE TABLE items
    • SQLite / PostgreSQL は DELETE FROM items (SQLite に TRUNCATE は無い・PostgreSQL は TRUNCATE もあるが ここでは DELETE で統一)
  3. 削除後にもう一度 SELECT COUNT(*) FROM items で件数を取り、after delete: {N} を出力

期待される出力

before: 3
after delete: 0

ヒント

  • scripts/shared/db-connect.phpdojo_db_connect() を使う
  • 件数取得は (int) $pdo->query("SELECT COUNT(*) FROM items")->fetchColumn() で 1 行
  • driver は getenv('DOJO_DB_DRIVER') ?: 'sqlite'
  • 文字列なので before: 3: の後ろにスペース 1 つ・改行で終わる点に注意

採点

php scripts/grade.php topics/11-db/ch11-mysql-specific/drill/03-truncate-vs-delete/

採点ランナーは driver に応じて setup.sql / setup.mysql.sql / setup.pgsql.sql を使い分け、items テーブルに 3 件入った状態から採点を始める。

学ぶこと (本質)

  • TRUNCATEDDL 扱い — 速いが ROLLBACK できない
  • DELETE FROMDML 扱い — トランザクションで取り消せる
  • 件数だけ見ると差は出ないが、直後の INSERT で振られる ID に差が出る:
    • TRUNCATE 後: 1 から振り直し
    • DELETE 後: 続きから (例: 元が 1,2,3 なら次は 4)
  • 本番のデータは原則 DELETE FROM ... WHERE ...TRUNCATEテスト DB のリセット で使う

テストケース

期待される出力

before: 3
after delete: 0

📄 starter.php(雛形)

このコードから書き始めてください。

<?php

require __DIR__ . '/../../../../../scripts/shared/db-connect.php';

$pdo = dojo_db_connect();
$driver = getenv('DOJO_DB_DRIVER') ?: 'sqlite';

// TODO:
// 1) SELECT COUNT(*) FROM items で件数を取り、"before: {N}" を出力
// 2) driver が 'mysql' なら TRUNCATE TABLE items、それ以外 (sqlite / pgsql) は DELETE FROM items を実行
// 3) もう一度 COUNT(*) を取り、"after delete: {N}" を出力
//
// 期待される出力:
//   before: 3
//   after delete: 0
✅ 解答例を見る(自分で解いてから)
<?php

require __DIR__ . '/../../../../../scripts/shared/db-connect.php';

$pdo = dojo_db_connect();
$driver = getenv('DOJO_DB_DRIVER') ?: 'sqlite';

$before = (int) $pdo->query("SELECT COUNT(*) FROM items")->fetchColumn();
echo "before: {$before}\n";

if ($driver === 'mysql') {
    $pdo->exec("TRUNCATE TABLE items");
} else {
    $pdo->exec("DELETE FROM items");
}

$after = (int) $pdo->query("SELECT COUNT(*) FROM items")->fetchColumn();
echo "after delete: {$after}\n";