Q1次のうち主キー(PRIMARY KEY)の説明として正しいものはどれですか。
テーブルの作成と定義変更
SQL のテーブル定義を基礎から学びます。CREATE TABLE による作成、PRIMARY KEY の指定、テーブル定義の確認、ALTER TABLE による列の追加・削除・改名まで、ブラウザで実行しながら押さえられます。
本講座で学ぶ SQL について
本講座で扱うのは、MySQL / Oracle / PostgreSQL / SQL Server など主要な RDBMS で共通して使える普遍的な SQL 構文 です。CREATE TABLE / SELECT / WHERE / JOIN / GROUP BY といった基礎は、どの DB に移っても同じ書き方でそのまま通用します。
ブラウザのコンソールは技術的制約から SQLite を採用していますが、DB ごとに異なる箇所(型の長さ強制、テーブル一覧の確認方法など)が出てきたら、MySQL ではこう書く のように他 DB の書き方も並べて紹介します。
テーブルとは
リレーショナルデータベースでは、データを テーブル(行と列からなる表)に格納します。1 つのテーブルは 列(カラム / column)と 行(レコード / row)で構成され、列ごとに格納できる値の データ型 が決まっています。
テーブル設計とは、どんな列を用意し、各列にどんな型を割り当てるかをあらかじめ決めることです。型が決まっていることで、想定外の値が入り込むのを防げます。
CREATE TABLE — テーブルの作成
テーブルを作るには CREATE TABLE 文を使います。テーブル名のあとに丸括弧を書き、その中に 列名 + 型 をカンマ区切りで並べます。最後の列のあとにはカンマを置きません。
型を最初に固めておくことで、想定外のデータ(数値列に文字列が混ざる等)が入りにくくなります。
-- 列名と型を並べてテーブルを作る
CREATE TABLE book_record (
id INTEGER,
title TEXT,
price INTEGER,
published_on TEXT
);
代表的なデータ型
SQL のデータ型は DB の種類に応じて名前と細部が異なりますが、最初は次の型を覚えておけば十分です。
| 型 | 格納する値 | 用途の例 |
|---|---|---|
| INTEGER | 整数 | id / age / count |
| REAL | 浮動小数点数 | score / weight |
| TEXT | 文字列 | name / address / message |
| BLOB | バイナリ | 画像・音声などのバイト列 |
| NUMERIC | 数値全般(日付・真偽値含む) | date / boolean を兼ねる |
MySQL の VARCHAR / CHAR / DATETIME はどう書く?
MySQL や PostgreSQL では VARCHAR(255) / CHAR(13) / BOOLEAN / DATETIME といった型を細かく指定して使います。これらは本講座のコンソールでも構文上はそのまま受け付けますが、長さ強制(VARCHAR(10) で 11 文字目を弾くなど)は MySQL や PostgreSQL のような 型を厳密に扱う RDBMS で初めて意味を持ちます。
本講座の演習では、列の型を INTEGER / TEXT / REAL を中心にシンプルに書きます。MySQL に移すときは INTEGER を INT、TEXT を VARCHAR(N) や TEXT に置き換えるだけで、CREATE TABLE の構造はそのままにできます。
PRIMARY KEY — 行を一意に識別する列
主キー(PRIMARY KEY、行を一意に識別するための列)は、テーブル内で 重複しない かつ NULL を許さない 値だけが入る列です。社員番号やユーザー ID のように「他と被らず必ず存在する」列を主キーにします。
主キーがあると、特定の 1 行を確実に取得できます。原則として、各テーブルに必ず 1 つ主キーを作成しましょう。
-- PRIMARY KEY を列定義の後ろに付ける
CREATE TABLE member (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
joined_on TEXT
);
INTEGER PRIMARY KEY は自動採番になる
INTEGER PRIMARY KEY と書いた列は、INSERT 時に値を省略すると 1 から順番に自動で番号が振られます。MySQL では同じ自動採番を id INT PRIMARY KEY AUTO_INCREMENT、PostgreSQL では id SERIAL PRIMARY KEY と書きます。本講座のコンソールでは INTEGER PRIMARY KEY だけで自動採番が効きます。
値を明示して INSERT した場合はその値が入り、次の自動採番はその次の整数から再開します。
制約違反を体験する — NOT NULL の働き
わざと違反してみて NOT NULL や PRIMARY KEY といった 制約(constraint = 列に入る値のルール)を確認しましょう。NOT NULL は その列に NULL を入れさせない ルールで、必須項目(名前・メールアドレスなど)に付けておくと、値が抜けた不完全な行の混入を未然に防げます。
冒頭で作成した user テーブルは name TEXT NOT NULL で定義されています。name 列に NULL を入れようとすると、DB はその INSERT を拒否してエラーを返します。
NOT NULL の列に NULL を入れる INSERT は弾かれてエラー。空文字('')は NULL とは別物として扱われるので、空文字での INSERT は通る点に注意します。-- 実践 3 で実行する INSERT (NOT NULL 制約違反を起こす)
INSERT INTO user (id, name, age, city)
VALUES (10, NULL, 30, 'Tokyo');
テーブルの確認と削除
テーブルを作ったあとは、どんな表があるか と その表がどんな列を持っているか を確認したくなります。本講座のコンソールでは次の 2 つで確認します。
- テーブル一覧: SELECT name FROM sqlite_master WHERE type='table';
- 列定義の確認: PRAGMA table_info(表名);
MySQL では SHOW TABLES; と DESCRIBE 表名;、Oracle では SELECT table_name FROM user_tables; のように、それぞれ専用の書き方があります。DROP TABLE でテーブルごと消すのは、どの DB でも共通の構文です。
-- ① テーブル一覧を表示
SELECT name FROM sqlite_master WHERE type='table';
-- ② user テーブルの列定義を表示
PRAGMA table_info(user);
-- ③ テーブルを消す
DROP TABLE IF EXISTS book_record;
ALTER TABLE — 既存テーブルの定義変更
運用が始まったあとで「列を 1 つ足したい」「テーブル名を変えたい」となったら ALTER TABLE を使います。本講座で扱う主な操作は次の 4 つで、どれも MySQL / PostgreSQL でもほぼ同じ構文で動きます。
| 操作 | 構文 | 用途 |
|---|---|---|
| テーブル名を変える | ALTER TABLE 旧名 RENAME TO 新名; | 表全体の改名 |
| 列を追加する | ALTER TABLE 表名 ADD COLUMN 列名 型; | 新しい属性を増やす |
| 列を削除する | ALTER TABLE 表名 DROP COLUMN 列名; | 不要になった属性を消す |
| 列名を変える | ALTER TABLE 表名 RENAME COLUMN 旧名 TO 新名; | 列の改名 |
MySQL の MODIFY / CHANGE COLUMN / AFTER
MySQL では ALTER TABLE 表名 MODIFY 列 型; で 列の型 を、CHANGE COLUMN 旧名 新名 型; で 列名と型を同時に、DROP PRIMARY KEY; で 主キー を変更できます。
-- 表全体の改名
ALTER TABLE user RENAME TO user_record;
-- 列の追加(末尾に email 列が増える)
ALTER TABLE user_record ADD COLUMN email TEXT;
-- 列名の変更
ALTER TABLE user_record RENAME COLUMN city TO area;
-- 列の削除
ALTER TABLE user_record DROP COLUMN email;
理解度チェック
まずは1問ずつ答えてみましょう。
Q2本講座のコンソールで user テーブルの列定義を確認したいとき、最も適切な書き方はどれですか。
Q3本講座のコンソールで ALTER TABLE を使うときの挙動として正しいものはどれですか。