#はじめに
夏ぼっちカレンダー(仮)の一日目の記事です。
主キーとIndexの違いがよく分からなくなるので、
整理しようと思います。
想定しているデータベース管理システムはMySQLです。
記事の中に間違いなどあれば指摘していただけると幸いです。
#主キーとは?
・primary keyとも呼ばれる(primaty keyの訳が主キー)
→ primaryは日本語で「主要の」という意味
・PRIMARY KEY制約をつけられたカラムに入るデータ
・NULL非許容、重複した値を入れることができない
→ テーブル内でのデータを一意に確定させることができる
##主キーは何のために必要?
・多くのデータの中で、データを一意に定めてくれるものがあれば、検索などが簡単になるから
本でいうISBNコードのようなもの、
ISBNコードが分かれば
どの本を指しているのかを世界中の書物から特定することができ、
その書物の情報を取得することができる。
ISBNとは
##主キーはこうして作られる
・PRIMARY KEY制約を設定して作られたカラムの中のデータが主キーになる
CREATE TABLE books{
book_id PRIMARY KEY,//この中に入るデータが主キー
name VARCHAR(255),
author VARCHAR(255),
publication_date DATETIME
};
上のCREATE文でできるテーブルに、データを一つ入れたもの↓
book_id | name | author | publication_date |
---|---|---|---|
1 | hoge | hogehoge | 2000/01/01 |
book_idカラムに設定されている「1」が主キー |
##PRIMARY KEY制約
・PRIMARY KEY制約はRDBで設定できる制約の一つ
以下のものが主な制約1
制約の種類 | 説明 |
---|---|
PRIMARY KEY制約 | 重複とNULLが許容されない、行がテーブル内で一意であることを確定させる |
UNIQUE制約 | NULLは許容する、値がテーブル内で一意であることを確定させる |
CHECK制約 | 指定した条件の値のみが保存されていることを確定させる |
DEFAULT制約 | 値が指定されないときに保存される値を決め、初期値を確定させる |
FOREIGN KEY制約(外部キー) | 別テーブルの主キーと参照整合性が保たれていることを確定させる |
上の制約はどれもカラムに入るデータに対する制約である、
一度int型の変数にする!と決めたらその後は
制約にそぐわないデータが入るのを防いでくれる。
(制約という形でデータを確認して予期せぬアクシデントを防ぐ)
PRIMARY KEY制約はテーブルの各カラムを作る際の設定の一つであり、
その制約をつけられたカラムの中のデータが主キーとなる。
###PRIMARY KEY制約の効果
PRIMARY KEY制約の効果は、
「重複とNULLが許容されない、行がテーブル内で一意であることを確定させる」
というもの
行がテーブル内で一意であることを確定させるので
例は以下のようになる。
許容される例
book_id | name | author | publication_date |
---|---|---|---|
1 | hoge | hogehoge | 2000/01/01 |
2 | fuga | fugafuga | 2010/12/25 |
3 | piyo | piyopiyo | 2000/01/01 |
PRIMARY KEY制約をつけられた
book_idカラムの中に入っているデータが
それぞれ異なっているので
book_idの値を指定すれば
全てのデータの中で必ずどれか一つを指していることになる
つまり「行がテーブル内で一意であることを確定させ」ていることになる
逆に以下のような例は入力の段階で弾かれる
許容されない例
book_id | name | author | publication_date |
---|---|---|---|
1 | hoge | hogehoge | 2000/01/01 |
2 | fuga | fugafuga | 2010/12/25 |
1 | piyo | piyopiyo | 2000/01/01 |
PRIMARY KEY制約をつけられた
book_idカラムの中に入っているデータに
重複があるので
book_idの値を指定しても
全てのデータの中でどれか一つを指すことができない
つまり「行がテーブル内で一意であることを確定させ」ることができていない
このようなデータは、データを入れようとしたときにエラーになる
##主キーまとめ
・PRIMATY KEY制約をつけられたカラムに入るデータ
・テーブル内でのデータを一意に確定させることができる
#Indexとは?
・日本語では「索引」という意味
・テーブルからデータを取り出すためのRDBMSの仕組み
・Indexを適切に作成し、検索時に使用することによってクエリを高速化することができる
##Indexは何のために必要?
・検索を速くするため
##Indexはこうして作られる
例えば、先に使用したbooksテーブルの中にデータが50万件くらい入っているとする。
そのデータの中から、特定のauthorのデータだけを抜き出したいとなった。
(それぞれのauthorのデータは50件くらい。)
単純に以下のクエリを使用すると時間がかかる。
SELECT * FROM books WHERE author = "piyo";
50万件のデータをフルスキャンして、
authorが合致するデータかどうかを
一つ一つ確認していくのでとても時間がかかる。
そこでauthorカラムにIndexを張る
CREATE INDEX author_idx ON books(author);
そうすると
対象のカラムのデータを取り出して、
高速に検索できるように昇順に並び替えたものが作成される
book_id | author |
---|---|
1 | hogehoge |
2 | fugafuga |
1 | piyopiyo |
これによって検索を速くすることができる。
#主キーとIndexの違い
・主キーは、「テーブル内でのデータを一意に確定させる」もの
・Indexは「検索」を速くするためのもの
作り方も目的も全く違うということが整理できました。
#なぜ主キーとIndexを混同してしまうのか?
主キーを作成すると自動的にIndexが張られる、かつ
whereやjoinする際に
主キーを使うことが多いので、
主キーが検索に使用される→検索を早くするためのIndexと混同する
ということが起こるのではないかなと思います。
#参考
曽根壮大著『失敗から学ぶRDBの正しい歩き方』株式会社技術評論社、2019年
西沢夢路『基礎からのMySQL 第3版』ソフトバンククリエイティブ株式会社、2017年
主キーとインデックスの違いについて
外部キー(foreign key)を作成するとインデックスもついてくる
プライマリキーとインデックスの違い
ソーシャルゲーム開発者なら知っておきたい MySQL INDEX + EXPLAIN入門
MySQLでインデックスを貼る時に読みたいページまとめ(初心者向け)
MySQLのインデックスの効果を理解する
MySQL初級者を脱するために勉強してること -INDEX編-
インデックスの意味とメリット・デメリット
-
曽根壮大著『失敗から学ぶRDBの正しい歩き方』株式会社技術評論社、2019年、2ページ ↩