理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

Learning SQL を読むことに

Interop に行ったときに,洋書は全部 1,000 円とかワケの分からないセールを O'Reilly ブースでやっていて (2008-06-12 - 理系学生日記),ぼくは ワケの分からないまま 4 冊くらい買ってやったんですけど,そのうちの一つが Learning SQL でした.

Learning SQL

Learning SQL

パーティとかも終わってようやく時間ができたような気がしますが,もちろんそれは気のせい,時間なんてないわけですけど,そんなのはムシだ.読みたいときに読みたいものを読むのが一番健康的だと不健康なぼくは思いますから,読めばいいんです読めば.飽きたら他の本を読んで,また戻ってくればいいんです! IPA の資格としてデータベースの試験があって,ぼくも一度とったんですけど,そのときはマジに資格を取るのが目的,結局データベースを使えてない人なので,今実際に触ってみればいいんです!

スキーマ作ってみようぜ

とりあえず Scheme を作ってみようぜってことで,CREATE TABLE などしてみる.

CREATE TABLE person
  (person_id SMALLINT UNSIGNED,
   fname VARCHAR(20),
   lname VARCHAR(20),
   gender ENUM('M', 'F'),
   birth_date DATE,
   address VARCHAR(30),
   city VARCHAR(20),
   state VARCHAR(20),
   country VARCHAR(20),
   postal_code VARCHAR(20),
   CONSTRAINT pk_person PRIMARY KEY (person_id)
  );

CONSTRAINT で指定されているのは,文字通り primary-key constraint (主キー制約).gender 欄の ENUM は,そのカラムに指定できる文字を限定することができるみたい.

  gender CHAR(1) CHECK (gender IN ('M','F'))

という感じに,check constraint としても書けるみたいだけど,MySQL だと ENUM でおkと.この違いがどう効いてくるのかは,まだ分からない.

確認してみる.

mysql> source ./create-person.sql
Query OK, 0 rows affected (0.00 sec)

mysql> DESC person;
+-------------+----------------------+------+-----+---------+-------+
| Field       | Type                 | Null | Key | Default | Extra |
+-------------+----------------------+------+-----+---------+-------+
| person_id   | smallint(5) unsigned | NO   | PRI | 0       |       |
| fname       | varchar(20)          | YES  |     | NULL    |       |
| lname       | varchar(20)          | YES  |     | NULL    |       |
| gender      | enum('M','F')        | YES  |     | NULL    |       |
| birth_date  | date                 | YES  |     | NULL    |       |
| address     | varchar(30)          | YES  |     | NULL    |       |
| city        | varchar(20)          | YES  |     | NULL    |       |
| state       | varchar(20)          | YES  |     | NULL    |       |
| country     | varchar(20)          | YES  |     | NULL    |       |
| postal_code | varchar(20)          | YES  |     | NULL    |       |
+-------------+----------------------+------+-----+---------+-------+
10 rows in set (0.01 sec)

おぉーーーーーー Scheme できてる! クール! クール!


次は外部キー制約のあるテーブルを作成する.なるほど,FOREIGN KEY で明示的に,どのテーブルのどのカラムに対する外部キーなのか,指定しないとならないわけね.よく考えれば,SQL Engine に外部キーの対象を見つけろっていうのも酷な話か.ちなみにこのテーブルは主キーが複合キーになっている例でもある.

CREATE TABLE favorite_food
  ( person_id SMALLINT UNSIGNED,
    food VARCHAR(20),
    CONSTRAINT pk_favorite_food PRIMARY KEY (person_id, food),
    CONSTRAINT fk_person_id FOREIGN KEY (person_id) REFERENCES person (person_id)
  );
mysql> DESC favorite_food
    -> ;
+-----------+----------------------+------+-----+---------+-------+
| Field     | Type                 | Null | Key | Default | Extra |
+-----------+----------------------+------+-----+---------+-------+
| person_id | smallint(5) unsigned | NO   | PRI | 0       |       |
| food      | varchar(20)          | NO   | PRI |         |       |
+-----------+----------------------+------+-----+---------+-------+
2 rows in set (0.30 sec)

あれ,KEY のカラムに外部キーである旨は出ないのか.表示的に主キーの方が外部キーより優先されるというのは直感的ではあるのだけれど.