ch11 — MySQL 固有の文法と運用
スライドで見るこの章を AI と学ぶ
演習問題の詳細
この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。
ドリル 01 — AUTO_INCREMENT で連番 ID を自動採番する
問題
items テーブル (採点ランナーが空で用意) に対して、PDO の prepared statement で次の 3 件を順番に INSERT する。
りんごみかんぶどう
INSERT 後に SELECT id, name FROM items ORDER BY id で取り出し、{id}: {name} の形式で 1 行ずつ出力する。
期待される出力
1: りんご
2: みかん
3: ぶどう
ヒント
scripts/shared/db-connect.phpのdojo_db_connect()を使うと driver を意識せず接続できるINSERT INTO items (name) VALUES (?)を 1 本だけprepare()し、execute()を 3 回呼ぶidは採点ランナーが用意したテーブルが SQLite ならAUTOINCREMENT、MySQL ならAUTO_INCREMENT、PostgreSQL ならSERIALで勝手に振られる- 取得時のソートは
ORDER BY idを必ず付ける (順序を担保するため)
学ぶこと
- MySQL の
AUTO_INCREMENT、SQLite のAUTOINCREMENT、PostgreSQL のSERIALは 文法は違うが結果は同じ - PDO 側からは「id を指定せず INSERT すれば勝手に振られる」だけを知っていれば良い
🧪 ブラウザで試す
スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。
PHP ランタイム未読込
ドリル 02 — テーブル一覧を取得する (driver 別の SHOW TABLES 相当)
問題
採点ランナーが users と posts の 2 テーブルを用意する。これらのテーブル名を アルファベット順 で 1 行ずつ出力する。
DB ごとにテーブル一覧の取り方が違うので、DOJO_DB_DRIVER (sqlite / mysql / pgsql) で分岐する。
| driver | 取り方 |
|---|---|
| sqlite | SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name |
| mysql | SHOW TABLES |
| pgsql | SELECT tablename FROM pg_tables WHERE schemaname = current_schema() ORDER BY tablename |
期待される出力
posts
users
ヒント
getenv('DOJO_DB_DRIVER') ?: 'sqlite'で driver 取得- PHP 8 の
match式で driver ごとに SQL を切り替えると見通しが良い SHOW TABLESは 1 列だけ返るのでFETCH_NUMで[0]を取り出すと簡単- MySQL/PostgreSQL は連想配列のキー名が DB によって変わる (e.g.
Tables_in_<dbname>) ので、列インデックス取得が無難 - アルファベット順なので
posts→usersの順 (採点ランナーは MySQL の SHOW TABLES もこの順で返す)
学ぶこと
- 「DB 内のテーブル一覧」は PDO で標準化されていない。DB ごとに違うクエリを叩く必要がある
- 逆に言えば、PDO のレイヤを抜けると DB 固有のメタデータ操作にすぐ手が届く
🧪 ブラウザで試す
スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。
PHP ランタイム未読込
ドリル 03 — TRUNCATE と DELETE の挙動を比較する
問題
採点ランナーが items テーブルに 3 件のレコードを用意する。
SELECT COUNT(*) FROM itemsで件数を取得し、before: {N}を出力- 全件削除する
- MySQL なら
TRUNCATE TABLE items - SQLite / PostgreSQL は
DELETE FROM items(SQLite に TRUNCATE は無い・PostgreSQL は TRUNCATE もあるが ここでは DELETE で統一)
- MySQL なら
- 削除後にもう一度
SELECT COUNT(*) FROM itemsで件数を取り、after delete: {N}を出力
期待される出力
before: 3
after delete: 0
ヒント
scripts/shared/db-connect.phpのdojo_db_connect()を使う- 件数取得は
(int) $pdo->query("SELECT COUNT(*) FROM items")->fetchColumn()で 1 行 - driver は
getenv('DOJO_DB_DRIVER') ?: 'sqlite' - 文字列なので
before: 3の:の後ろにスペース 1 つ・改行で終わる点に注意
学ぶこと (本質)
TRUNCATEは DDL 扱い — 速いが ROLLBACK できないDELETE FROMは DML 扱い — トランザクションで取り消せる- 件数だけ見ると差は出ないが、直後の INSERT で振られる ID に差が出る:
- TRUNCATE 後: 1 から振り直し
- DELETE 後: 続きから (例: 元が 1,2,3 なら次は 4)
- 本番のデータは原則
DELETE FROM ... WHERE ...。TRUNCATEは テスト DB のリセット で使う
🧪 ブラウザで試す
スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。
PHP ランタイム未読込
演習問題(3問)
-
ドリル 01 — AUTO_INCREMENT で連番 ID を自動採番する
-
ドリル 02 — テーブル一覧を取得する (driver 別の SHOW TABLES 相当)
-
ドリル 03 — TRUNCATE と DELETE の挙動を比較する
サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。
完了にすると進捗に反映されます