Day3 後半のゴール
「1つのテーブルで“CREATE→INSERT→SELECT→UPDATE→DELETE”を一気に通す」
後半は、頭での理解ではなく「手で覚える」時間です。
やることはシンプルで、これだけです。
1つテーブルを作る
データを入れる
読み出す
更新する
削除する
SQLiteでやってきたことを、MySQLの文法とクセでなぞり直します。
その中で、AUTO_INCREMENT や DATETIME の動きも一緒に確認します。
例題テーブル:簡易タスク管理
「現実のイメージが湧く題材でやると定着しやすい」
題材として「タスク管理」を使います。
やりたいことはこんな感じです。
タスクにID・タイトル・状態・作成日時を持たせる
タスクを追加する
未完了のタスクだけを見る
タスクを完了に更新する
終わったタスクを削除する
これを1つのテーブルでやってみます。
CREATE TABLE:タスクテーブルを定義する
「型・AUTO_INCREMENT・InnoDB を“いつもの形”で書く」
まずはテーブル定義です。
CREATE TABLE tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at DATETIME NOT NULL
) ENGINE=InnoDB;
SQLここに、MySQLらしさが全部入っています。
id は INT AUTO_INCREMENT PRIMARY KEY
タイトルは最大100文字の VARCHAR
状態(status)は “todo / doing / done” などを想定して VARCHAR(20)
作成日時は DATETIME
エンジンは InnoDB
SQLiteなら id INTEGER PRIMARY KEY, title TEXT, status TEXT, created_at TEXT くらいで済ませていたかもしれません。
MySQLでは「何が文字列で、何が日時で、何がIDか」をはっきり分けているのがポイントです。
INSERT:タスクを追加する
「id を書かずに、NOW() で現在時刻を入れる」
タスクを2件追加してみます。
INSERT INTO tasks (title, status, created_at)
VALUES
('MySQLの環境構築', 'todo', NOW()),
('Day3の復習', 'todo', NOW());
SQLここで意識してほしいのは2つです。
id を指定していない
→ AUTO_INCREMENT が勝手に 1,2,… を振ってくれる
created_at に NOW() を入れている
→ DATETIME として「今の時刻」が入る
確認してみます。
SELECT * FROM tasks;
SQLid が 1,2 になっていて、
created_at にちゃんと日時が入っていればOKです。
SQLiteのときと同じ感覚で書けているのに、
中身は「型がちゃんとしている」「IDはAUTO_INCREMENT」という MySQL流になっています。
SELECT:未完了タスクだけを取得する
「WHERE で条件を絞る基本を、“現実の条件”で確認する」
次に、「未完了(todo)のタスクだけ欲しい」とします。
SELECT id, title, status, created_at
FROM tasks
WHERE status = 'todo'
ORDER BY id;
SQLやっていることはシンプルです。
tasks テーブルから
status が ‘todo’ の行だけを
id 順に並べて取得する
SQLiteと文法はほぼ同じですが、
ここで「status を VARCHAR(20) にした意味」が効いてきます。
status を INT にして「0=todo, 1=done」でもよかったかもしれません。
その場合は WHERE status = 0 になります。
どちらを選ぶかは設計次第ですが、
MySQLでは「型をどうするか」がクエリの書きやすさにも直結します。
UPDATE:タスクを完了にする
「WHERE で“1件だけ”を狙い撃ちする感覚」
タスクID 1 を「done」に更新してみます。
UPDATE tasks
SET status = 'done'
WHERE id = 1;
SQLここで一番大事なのは、
WHERE で「id = 1」と明確に指定していることです。
もし WHERE を書き忘れると、
全タスクの status が ‘done’ になります。
実務では、UPDATEを書く前に必ず、
SELECT * FROM tasks WHERE id = 1;
SQLで対象を確認する癖をつけます。
これはSQLiteでも同じですが、
MySQLは本番で使われることが多いので「事故ったときの被害」が桁違いです。
確認してみます。
SELECT * FROM tasks;
SQLid=1 の status だけが ‘done’ になっていれば成功です。
DELETE:終わったタスクを削除する
「“本当に消していいか”を自分に問いかける」
例えば、「完了したタスクは消してしまう」という仕様にするとします。
id=1 のタスクを削除してみます。
DELETE FROM tasks
WHERE id = 1;
SQLこれも、必ず WHERE を付けます。DELETE FROM tasks; と書くと全削除です。
削除後に確認します。
SELECT * FROM tasks;
SQLid=2 のタスクだけ残っていればOKです。
ここで、1つ考えてほしいことがあります。
本当に物理削除でいいのか?
「削除フラグ(is_deleted)」を立てるだけの方が安全では?
MySQLのようなサーバーDBでは、
「DELETE は最終手段」「まずは論理削除で」という設計もよくあります。
Day3の段階では、
「DELETE は戻せない」「慎重に使う」
この感覚だけ持っておけば十分です。
一連の操作を通して見える“差分”
「書き方は同じでも、“設計と責任の重さ”が違う」
ここまでの流れをまとめると、
CREATE TABLE
→ 型・AUTO_INCREMENT・ENGINE=InnoDB を意識して定義
INSERT
→ id を書かずに、NOW() で日時を入れる
SELECT
→ WHERE で条件を絞り、ORDER BY で並べる
UPDATE
→ WHERE で対象を絞り、先に SELECT で確認する
DELETE
→ WHERE を必ず付ける、“戻せない操作”だと理解する
文法だけ見れば、SQLiteとほぼ同じです。
でも、MySQLでは、
型をちゃんと決めている
IDをAUTO_INCREMENTに任せている
InnoDBを前提に「ちゃんとしたDB」として扱っている
本番運用を意識して、UPDATE/DELETEに慎重になっている
という“設計と責任の重さ”が一段階上がっています。
セキュリティ・安全性の視点から見た基本操作
「小さなテーブルでも、“雑に触らない”癖をつける」
Day3のような小さな例でも、
セキュリティ・安全性の観点はすでに入り込んでいます。
IDをAUTO_INCREMENTにする
→ メールアドレスなど“意味のある値”を主キーにしない
→ 情報漏えい時のリスクを下げる
型をきちんと決める
→ ありえない長さの入力を最初から受け付けない
→ 変なデータが入りにくくなる
UPDATE / DELETE で必ず WHERE を付ける
→ 誤操作による大量更新・大量削除を防ぐ
→ データの安全性を守る
こうした「小さな当たり前」を、
Day3の段階から体に染み込ませておくと、
後で大きなシステムを触るときに効いてきます。
Day3 後半のまとめ
1つのテーブル(tasks)を使って、CREATE TABLE → INSERT → SELECT → UPDATE → DELETE の一連の流れを MySQL で通すと、SQLiteと文法はほぼ同じでも、「型・AUTO_INCREMENT・ENGINE=InnoDB」を前提にした“ちゃんとしたDB”として扱っている感覚が身につく。
INSERT では id を指定せずに AUTO_INCREMENT に任せ、日時は DATETIME+NOW() で入れることで、「IDは内部用の連番」「日時は文字列ではなく時間として扱う」という MySQL流の設計が自然に身につく。
UPDATE / DELETE は、WHERE を必ず付ける・先に SELECT で対象を確認する、という“慎重さ”が何より重要で、サーバーDBであるMySQLでは誤操作の影響が大きいため、この習慣がそのままデータの安全性につながる。
ここまでできていれば、
「MySQLだからといって基本操作で迷う」ことはほぼなくなっています。
次のステップでは、JOIN やインデックスなど、「MySQLを本番っぽく使う」ための要素に進んでいけます。
