コース一覧
SQL実践:JOIN・サブクエリ・データ更新
ALTER TABLE で構造を変更する

SQL実践:JOIN・サブクエリ・データ更新

JOIN、集合演算、サブクエリ、CTE、DDL・DMLを学び、複数テーブルを組み合わせてデータベースを作成・更新する無料コースです。

1
テーブル結合
01. なぜ結合が必要か5分
02. INNER JOINの基本5分
03. LEFT/RIGHT OUTER JOIN5分
04. 複数テーブルの結合5分
05. 自己結合5分
06. 集合演算 UNION/INTERSECT/EXCEPT5分
07. 結合の実践演習5分
08. テーブル結合クイズ5分
2
サブクエリ活用
01. サブクエリとは5分
02. WHERE句のサブクエリ5分
03. FROM句のサブクエリ5分
04. SELECT句のサブクエリ5分
05. WITH句(CTE)の活用5分
06. サブクエリ実践クイズ5分
3
テーブル作成とデータ操作
01. CREATE DATABASE と CREATE TABLE5分
02. データ型の選び方5分
03. INSERT 文でデータを追加する5分
04. UPDATE 文でデータを更新する5分
05. DELETE 文でデータを削除する5分
06. 物理削除と論理削除5分
07. ALTER TABLE で構造を変更する5分
08. 制約 (NOT NULL / UNIQUE / DEFAULT)5分
09. TRUNCATE と DROP5分
10. DDL / DML 実践クイズ5分

ALTER TABLE で構造を変更する

動いているテーブルに、列を 1 本足したい

テーブル設計は一度作って終わりにはなりません。「投稿に公開範囲を持たせたい」「使わなくなった列を消したい」という要求は、サービスが伸びるほど増えます。すでにデータが入っているテーブルの形を変える命令が ALTER TABLE で、アプリ開発の現場では「マイグレーション」と呼ばれます。

やっかいなのは、その間もテーブルが使われ続けていることです。走っている車のタイヤを、走ったまま替えるようなものだと思ってください。

いきなり NOT NULL を付けると失敗する

たとえば posts テーブルに公開範囲の列を足すとします。最初から NOT NULL を付けたくなりますが、すでに入っている行に何を入れるかが決まっていないので、この ALTER は失敗します。

そこで 3 回に分けます。

SQL クエリ

-- 1. まず NULL を許す形で足す。既存の行は NULL のまま
ALTER TABLE posts ADD COLUMN visibility VARCHAR(20);

-- 2. 既存の行を埋める
UPDATE posts SET visibility = 'public' WHERE visibility IS NULL;

-- 3. 埋め終わってから締める
ALTER TABLE posts ALTER COLUMN visibility SET NOT NULL;

1 と 3 の間もアプリは動き続けているので、新しく入る行にも値が入るよう、書き込み側を先に直しておきます。この順番を守ると、本番を止めずに列を足せます。

ADD COLUMN に DEFAULT を付けて一発で済ませる書き方もありますが、既存の全行にその値を書き込む処理が走ります。行が少ないうちは一瞬で終わり、多くなると 2 の UPDATE を一度に流したのと同じ重さになります。1 万行なら気にせず、100 万行なら分けて考える、くらいの感覚で構いません。

列を消すのは、足すより怖い

列を消した瞬間、その列を読んでいたクエリが一斉に落ちます。

SQL クエリ

ALTER TABLE posts DROP COLUMN legacy_flag;

打つ前に、アプリのコードと SQL を検索して参照がゼロであることを確かめます。「たぶん使っていない」で消すと、月次バッチだけが翌月に落ちる、という気づきにくい壊れ方をします。

列名の変更も同じ理由で危険です。

SQL クエリ

ALTER TABLE posts RENAME COLUMN body TO content;

これを一発で流すと、旧名で動いている古いアプリと新名を期待する新しいアプリが同時に走る瞬間に、片方が壊れます。実務では「新しい列を足す」「両方に書く」「読み先を新しい列へ移す」「旧列を消す」の 4 回に分けます。列を足すときの 3 段階と発想は同じで、切り替えの瞬間を作らないようにしています。

解説

ALTER TABLE は軽い操作に見えますが、内容によってはテーブル全行の検査や書き換えが走ります。1000 万行のテーブルに流して 30 分ロック、は珍しくありません。行数が多いテーブルでは、実行前に所要時間を見積もるところから始めます。

テーブル構造

CREATE TABLE customers (
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

INSERT INTO customers (id, name) VALUES
  (1, '田中太郎'),
  (2, '佐藤花子'),
  (3, '山田次郎');

期待される出力

idnamemember_rank
1田中太郎bronze
2佐藤花子bronze
3山田次郎bronze

ヒント

ALTER TABLE ... ADD COLUMN 列名 型 で列を追加

UPDATE で既存行に値を埋めてから NOT NULL 化する

ALTER TABLE ... ALTER COLUMN 列名 SET NOT NULL で締める

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • テーブルDB の表 (Excel のシートみたいなもの)
  • 設計何をどう作るかを決める前工程
  • 処理計算や代入を表す長方形
  • SQLデータベースを操作するための共通言語
  • ロック「他の人触らないでね」と DB に予約する
query.sql
学習モード
エディタを読み込んでいます
コードの実行結果
データベースを初期化中...