STAGE 06 — 6-3 / データの操作

CREATE TABLEと制約

考えてみよう

もしアマテラスのデータベースを、あなたが一から作るとしたら——crewというテーブルを、どんな形で用意しますか? これまでは「すでにある表」を前提に学んできましたが、今回はその表自体を作ります。

表の名前を決めるだけでなく、どんな列を持ち、それぞれにどんな種類のデータが入るのかまで、あらかじめ決めておく必要があります。少し考えてから読み進めてください。

CREATE TABLE の基本形

テーブルそのものを新しく作るには、CREATE TABLE文を使います。

CREATE TABLE テーブル名 (
  列名1 型,
  列名2 型,
  ...
);

crewテーブルを、実際に定義してみましょう。

CREATE TABLE crew (
  id INTEGER,
  name TEXT,
  role TEXT,
  age INTEGER,
  home TEXT,
  salary INTEGER
);

これで、まだ1行もデータが入っていない、空のcrewテーブルができあがりました。ここに前回学んだINSERT文でデータを入れていけば、これまで学んできたcrewテーブルそのものが出来上がります。

列と型 ― 代表的な2つ

それぞれの列名のうしろにある INTEGERTEXT は、その列にどんな種類のデータが入るかを決める「型」です。よく使う代表的な型は、次の2つです。

型を決めておくことで、データベースは「ageの列に文字列を入れようとしたら弾く」といったチェックができるようになります。型は、テーブルという入れ物に「この引き出しには数字だけ、この引き出しには文字だけ」というラベルを貼る作業だとイメージしてください。

PRIMARY KEY ― この列が主キーです、と宣言する

STAGE01で、行を一意に識別する主キーという考え方に触れました。CREATE TABLEでは、その主キーがどの列かを、実際に宣言します。

CREATE TABLE crew (
  id INTEGER PRIMARY KEY,
  name TEXT,
  role TEXT,
  age INTEGER,
  home TEXT,
  salary INTEGER
);

id INTEGER PRIMARY KEY と書くことで、「idの値は、この表の中で他の行と重複してはいけない」というルールをデータベース自身に守らせることができます。同じidを持つ行を2つ登録しようとすると、データベース側がエラーを出して止めてくれます。

NOT NULL ― 空を許さない

列によっては、「値が入っていない状態」を絶対に許したくないものがあります。たとえば乗組員に名前がない、という状態は考えられません。そんな列には NOT NULL を付けます。

CREATE TABLE crew (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  role TEXT,
  age INTEGER,
  home TEXT,
  salary INTEGER
);

name TEXT NOT NULL と書くと、name を空のままINSERTしようとした場合に、データベースがエラーを返して拒否してくれます。「入っていて当然のデータ」には、あらかじめNOT NULLを付けておくことで、不完全なデータが紛れ込むのを未然に防げます。

外部キーの宣言

STAGE05で学んだ crew_idplanet_id のような外部キーも、CREATE TABLEの時点で宣言しておくことができます。missionsテーブルを定義してみましょう。

CREATE TABLE missions (
  id INTEGER PRIMARY KEY,
  title TEXT NOT NULL,
  crew_id INTEGER,
  planet_id INTEGER,
  reward INTEGER,
  status TEXT,
  FOREIGN KEY (crew_id) REFERENCES crew(id),
  FOREIGN KEY (planet_id) REFERENCES planets(id)
);

FOREIGN KEY (crew_id) REFERENCES crew(id) は、「このmissionsテーブルのcrew_id列は、crewテーブルのid列を参照していますよ」という宣言です。この宣言があることで、データベースは「存在しないcrew_idを持つ任務が登録される」といった、表と表の間の矛盾(壊れた参照)を防いでくれます。STAGE05で学んだJOINがスムーズにできていたのは、まさにこの外部キーの宣言によって、2つの表がきちんと関連づけられていたからなのです。

確認問題

「このmissionsテーブルのcrew_id列は、crewテーブルのid列を参照している」ということを、CREATE TABLEの中で宣言するキーワードは何でしょう?

答えを見る

FOREIGN KEYです。FOREIGN KEY (crew_id) REFERENCES crew(id) のように書くことで、列同士の参照関係をデータベースに宣言できます。

これにより、存在しないcrewのidを持つ任務が登録されるといった、表と表の間の矛盾をデータベース自身が防いでくれます。

講座全体のまとめと次の一歩

ここまでの全6ステージを、駆け足で振り返ってみましょう。STAGE01〜02でデータベースとテーブルの基本、SELECTでの取り出し方を学び、STAGE03で WHERE による絞り込みと並べ替え、STAGE04で GROUP BY HAVING による集計を学びました。そしてSTAGE05で複数の表を JOIN でつなげる方法を、STAGE06で INSERT UPDATE DELETE CREATE TABLE によるデータそのものの操作と定義を学びました。

「表を作り(CREATE TABLE)→データを入れ(INSERT)→取り出し(SELECT)→絞り込み・集計・結合し(WHERE・GROUP BY・JOIN)→書き換え・削除する(UPDATE・DELETE)」——これでデータベースを扱う一連の流れが、ひととおりつながったことになります。

次の一歩としておすすめしたいのは、実際にSQLiteやMySQLなど本物のRDBMSをパソコンにインストールし、自分で考えたテーブルを実際にCREATE TABLEしてみることです。この講座では標準的なSQLの基礎に絞って解説してきましたが、この先には副問い合わせ(サブクエリ)やトランザクション、インデックスといった、さらに実務的なテーマが待っています。焦らず、今回学んだ基礎を土台に、少しずつ広げていってください。

ゆみちゃん
ゆみ

STAGE01からここまで、本当によく頑張ったね! 表を分けて、SELECTで取り出して、WHEREで絞り込んで、JOINでつなげて、INSERT・UPDATE・DELETEで動かす——これでSQLの基本の一周がしっかり身についたはず。ここからは、実際のRDBMSで自分の手を動かしながら、少しずつ世界を広げていってね。お疲れさま!

手元のSQLiteなどで、実際にCREATE TABLEを打ち込んで自分だけのテーブルを作ってみるのもおすすめです。そして総仕上げには、ぜひもう一度SQL DIVERでSELECT・WHERE・JOINをタイプして、この講座で身につけた感覚を指に染み込ませてみてください。