chapter1

リレーショナルデータベースって便利だよねーって話。 E.F.coddが最初の論文を出したってことだけ覚えておくとかっこいいかもしれないね。

chapter2

データのインポート、エクスポート

外部データのインポート方法をここで説明している。

Mysql公式のチュートリアル用データ ここからほしいデータをダウンロードしてきて、mysql内部から次のコマンドでロードできる

mysql -u ray -p 
mysql> source <path/to/schame/sakila-schedma.sql>
mysql> source <path/to/data/sakila-data.sql>

って感じやな。ちなみに、自分が作ったデータを外部にエクスポートする方法もあって、

# データベース
$ mysqldump -u USER_NAME -p -h HOST_NAME DB_NAME > OUTPUT_FILE_NAME

# テーブル
$ mysqldump -u USER_NAME -p -h HOST_NAME DB_NAME TABLE_NAME > OUTPUT_FILE_NAME

# テーブルの定義とデータのダンプ
$ mysqldump -u USER_NAME -p -h HOST_NAME -A -n > OUTPUT_FILE_NAME 

まあ調べたらあるから調べてみてくれ。データベースの移行はそんなに難しいことではないことだけ頭に入れておいてほしい。

ちなみに、mysqlでのschemaの見方は、

describe customer;

忘れがちだから覚えておいてください!!まじで!!describeを短縮してdescでもオッケーです。

SELECT
  TABLE_NAME
, COLUMN_NAME
, COLUMN_TYPE
, COLUMN_KEY
FROM
  INFORMATION_SCHEMA.COLUMNS
WHERE
  TABLE_SCHEMA = 'sakila'
;

データ型について

日付に関するデータ型だけ。

date  : YYYY-MM-DD
datetime YYYY-MM-DD HH:MI:SS
timestamp YYYY-MM-DD HH:MI:SS
year YYYY
time HHH:MI:SS

DDLについて

data definition languageとは、create,drop,alter,truncateの4つですね。まあ、create死活風は使わないと思います。 これを学んでいきましょう。

create

CREATE TABLE person(
    person_id SMALLINT UNSIGNED AUTO INCREMENT, 
    fname VARCHAR(20),
    lname VARCHAR(20),
    eye_color CHAR(20),
    birth_date DATE,
    street VARCHAR(30),
    city VARCHAR(20),
    state VARCHAR(20),
    country VARCHAR(20),
    postal_code VARCHAR(20),
    PRIMARY KEY (person_id),
)

CREATE TABLE favorite_food(
    person_id SMALLINT UNSIGNED,
    food VARCHAR(20),
    CONSTRAINT pk_favorite_food PRIMARY KEY (person_id,food),
    FOREIGN KEY (person_id) REFERENCES person (person_id)

)

ここ結構重要かもしれない。おれはいままで、わざわざ一つ主キーを定めないと思っていたけど、複数のカラムをつかってしゅきーにすることもできるって話。これ大事ね。

DML

select,insert,update,delete

insert

INSERT INTO favorite_food (person_id,foot)
VALUES(1,'pizza')

っていう、この方法で、挿入するってことだけ覚えてください。

select

SELECT food FROM favorite_food
WHERE person_id = 1
ORDER BY food;

update

chapter3

SQLの概要について説明してくれています。 クライアントでサーバに接続して、権限があるか確認して、みたいな。で、クエリは最初にクエリオプティマイザに渡される、とかね。で、クエリオプティマイザがどの順番で実行するか、実行プランを調べると。

実行プランを選択する方法を理解したければ、「High performance MySQL」という本が参考になるらしいです。

クエリの句について

select,from,where,group by,having, order byを覚えておきましょう。 で、 where : 不要なデータを取り除く group by : 共通の列の値に基づいて行をグループ化する having : 不要なグループを取り除く

select句について

select句はselect文の最初の句ですが、データベースサーバが最後に評価する句。そうなんです、これ大事だね。というのも、最終的な結果セットに含まれるものを判断するには、最終的な結果セットに含まれる可能性がある列を全て洗い出す必要があるからです。

つまり、select句の役割はこうだ

  1. 数字や文字列などのリテラル
  2. transaction.amount * -1
  3. round() などの組み込み関数
  4. ユーザ定義の関数呼び出し が定義できる。次のようなことができる。
SELECT language_id,
'COMMON' as language_usage,
language_id * 3.1415 as lang_pi_value,
upper(name) as language_name
FROM language

asで列エイリアスを指定している。また、asは省略もできる。が、個人的には省略したくないです。

from句

from句は、クエリに使うテーブルと、テーブル同士をリンクする方法を定義する。

難しいね、これを理解するには2つの概念を知らないと行けない。テーブルとリンクね。

テーブルについて

テーブルは全部で4種類あると。

  1. 永続テーブル (create table文を使って作成したテーブル) 普通のやつ

  2. 派生テーブル (サブクエリによって返され、メモリ内で保持される行セット)

SELECT concat (cust.last_name,',',cust.first_name) as full_name
from 
(SELECT first_name, last_name,email
FROM customer
WHERE first_name = 'JESSIE')
as cust;

って感じで、FROM句の中でサブクエリを使うときは、派生テーブルを生成するという役割を担っているんですね。

  1. 一時テーブル (メモリ内の揮発データ) 永続テーブルと同じに見えるけど、セッションが閉じると消えてしまうものが一時テーブル。メモリ上に一時的に保存しておくものだね。
CREATE TEMPORARY TABLE actors_j(
actor_id smallint(5),
first_name varchar(45),
last_name varchar(45)
);

INSERT INTO asctores_j
select acgtor_id,first_name,last_name
from acgtor
wehre last like 'J%'
  1. 仮想テーブル (create view文を使って作成したテーブル)

まあ、がんばってくれ

リンクについて

まあ、joinについてだな。 from join on 条件。っていう流れは絶対に覚えておいたほうがいいで。あと、left join と right joinね。

where句

まあ、不必要なものを除く役割、ってことだけ覚えておいてください。以上

group byとhaving句

グループ化して、数えたりできるってことです。これは結構便利ですね。グループごとの最大値や最小値、カウントとか結構かんたんにできてしまいます。いいSQL文があったので、それをここで紹介したいと思います。

SELECT c.first_name, c.lst_name, count(*)
FROM customer as c
    INNER JOIN rental as r
    ON c.customer_id = r.customer_id
GROUP BY c.first_name, c.last_name
HAVING count(*) >= 40;

はい、まず重要な点はinnner joinですね。innerは省略もできまして、しょりとしては、「2つのテーブルの合体可能なデータのみ取り出す」なので、rentalの方に複数の同じcustomer_idがあっても、全部つなげてくれます。ちょっとright joinに似てる気もするのですが、right joinは合体不可能なやつも残るってところが違いますね。 ポイントの2つ目は、count(*)ですね。まあ、groupbyする目的は、groupごとの何かを知りたいからです。はい、以上。で、havingはgroup化したときのwhere句と同じだと思ってもらってokです。

chapter4 フィルタリング

条件の評価

ANDとORの使い方、()で囲まないと行けない条件などを説明しています。 NOT演算子も使うことができますよと。

条件の種類

等号条件:=

範囲条件: >=, >, <, <= メンバーシップ条件:inですね。これ大事。あまり使わないから。

select title,rating
from film
where rating IN ('G','PG')

マッチング条件: likeと一緒に使うんだよね。で、ワイルドカードもここで覚えておいてほしいです。 任意の個数の文字:% ちょうどいち文字:_

chapter5 内部結合

直積と内部結合について

joinは外部キーで紐付けられているテーブル間で実行される。つまり、foreign keyがjoinをするための役割を担っている。これは当たり前だけど、重要だよね。 で、joinするときに、とくにon customer.id = rental.idとかで指定しないと直積集合が出てくる。クロス積とも言います。しかし、これはめったに使わないみたいです。 で、onを指定すると、全部の組み合わせを出してきた直積から該当するものだけを持ってくることが可能になるわけですね。

select c.first_name, c.last_name,a.address from customer as c
join address as a
on c.address_id = a.address_id;

3つ以上のテーブルを結合する

まあかんたんよ。

select c.first_name,c.last_name,ct.city
from customer as c
join address as a on c.address_id = a.address_id
join city as ct on a.city_id = ct.city_id;

サブクエリをテーブルとして使う

これは重要です。

select c.first_name, c.last_name, addr.address, addr.city
from customer as c
join 
(
  select a.address_id, a.address, ct.city
  from address as a 
  join city as ct
  on a.city_id = ct.city_id
  where a.district = 'California'
) as addr
on c.address_id = addr.address_id;

サブクエリで何が起こっているかわからないときは、とりあえず、サブクエリ単体で実行してみよう!!って話です。

同じdテーブルを2回使う必要がある場合

問題: cate acqueeと cuba birchが共演している映画を探せ!! こレをやるには、

select f.title
from film as f
join film_actor as fa
on f.film_id = fa.film_id
join actor as a1
on fa.actor_id = a1.actor_id
join film_actor fa

ちょっとめんどくさいので飛ばします!!

ちなみに、ここで重要なことを書きます。 NOsqlはkey-valueストアと考えていいでしょう。で、joinする必要がなければ、nosqlが使えるということです。 データウェアハウスなど、複雑なデータ構造が必要なビジネスシーン等ではnosqlは使えませんが、joinが必要ないような単純な データ処理の場合は、nosqlが使えるでしょう。それこそ、競馬の時系列データなんかはいい例だと思います。 しかし、どうやらカラム指向型のNOsqlを使うと、ジョインというか、複数のテーブルのようなものに渡るデータを定義することが可能になるみたいです。ツイッターとか、cassandra上で動いているらしいしね。

6章

7章

8章 グループ化

ここもじゅうようだねー。 まず大事なのは、 group by aでグループかして、そのaを表示すると、重複がなくなって出てくるってこと。内部的にはグループ化されているんだけど。

select customer_id from rental  group by  rental.customer_id;

こうやると、customer_idが一意に出てくるわけです。 で、ここにcount(*)を加えることで、それぞれのカウントが出てくるんですよね。countはグループの行の個数をカウントしてくれるんですね。便利です。ちなみに、group_byが評価されるのは、whereのあとだから、gropu byのあとにwhereを使うことはできません。代わりに使えるのが、havingってことですね。かんたんです。

集計関数

max,min,avg,sum,countの5つを覚えておけばいいでしょう。group byと集計関数はセットで覚えましょう。

9章 サブクエリ