MySQLのデータ型について

はじめに

本気記事ではMySQLのデータ型について書いていきたいと思います。
データ最適なデータ型を選ぶことは高速化にもつながります。
データ型を選ぶにあたり

  • データ型はなるべく小さいほうがよい
  • 単純なものがよい(文字列よりも整数のほうが早いなど)
  • できればNULLを使用しない

は最低限検討してみてもよいでしょう。
今回書いていくデータ型は大まかに以下のものについてです。

  • 整数型
  • 実数型
  • 文字列型
  • 日付と時刻型

整数型

整数型には以下のものがあります。

型名 記憶容量 範囲 範囲(UNSIGNED)
TINYINT 8ビット -128~127 0~255
SMALLINT 16ビット -32,768 ~ 32,767 0~65535
MEDIUMINT 24ビット -8,388,608~8,388,607 0~16,777.215
INT 32ビット -2,147,483,648 ~ 2,147,483,647 0~4,294,967,295
BIGINT 64ビット -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 0~18,446,744,073,709,551,615

符号付と符号なし(UNSIGNED)は記憶容量は同じでパフォーマンスも同じになるのでデータ範囲に適したほうを使用したらよいと思います。
またINT(5)のように幅を指定できるがこれは有効な範囲を指定しているものではないみたいです。
INT(5)とやってもINTの範囲内であれば6桁以上の数値も入ります。
つまりはINT(5)やINT(10)は記憶容量や範囲は同じものとなります。

実数型

実数型には以下のものがあります。

  • FLOAT : 4バイ
  • DOUBLE : 8バイ
  • DECIMAL : 記憶容量は可変する

基本的には記憶容量が小さいほうが速度は速いのでFLOATが一番速いが精度が低く範囲が狭くなってしまう。
またDECIMAL型は全体の表示幅と小数部の最大桁数の指定ができる。
例えば小数部を9桁、全体を18桁にしたい場合は
DECIMAL(18,9)
と指定します。
この時の記憶容量は4バイトで9桁記憶できるので18桁で8バイトと小数点に1バイト使うので、合計で9バイトの記憶容量になります。
またDECIMALは記憶域と計算上のコストが増えるので代わりに値を100万倍などをしBIGINTなどを使うことを考えることもできると思います。

文字列型

文字列型には以下のものがあります。

  • VARCHAR
  • CHAR
  • BLOB
  • TEXT
VARCHAR

VARCHARは可変長で文字列を格納します。そのため必要な記憶領域しか使用しないため、固定長のかたほど多くの記憶領域を必要としません。

CHAR

CHARは固定長の文字型である。CHARは非常に短い文字列を格納したい場合や、すべての値がほぼ同じ長さである場合に有用す。

BLOB

BLOB型はバイナリーデータを扱う型で、格納できるデータサイズの指定を行いません。ただし最大長は決まっています。

  • TINYBLOB : 最長255
  • BLOB : 最長65,535
  • MEDIUMBLOB : 最長16,777,215
  • LONGBLOB : 最長4,294,967,295
TEXT

TEXT型は文字列データを扱う型で、格納できるデータサイズの指定を行いません。ただし最大長は決まっています。

  • TINYTEXT : 最長255
  • TEXT : 最長65,535
  • MEDIUMTEXT : 最長16,777,215
  • LONGTEXT : 最長4,294,967,295

日付と時刻型

日付と時刻型には以下のものがあります。

型名 記憶容量
DATETIME 8バイ
TIMESTAMP 4バイ

DATETIMEは1001~9999年までの値を格納することができ、精度は1秒である。
日付と時刻をYYYYMMDDHHMMSS形式で整数にパックする。
TIMESTAMPは1970年1月1日午前0時グリニッジ標準時からの経過時間を秒数で格納します。なので範囲は1970年から2038年の途中までとなっています。

まとめ

今回の記事では以下のデータ型について書いていきました。

  • 整数型
  • 実数型
  • 文字列型
  • 日付と時刻型

それぞれ特徴があるのでその時々にあったデータ型の選択をしていきましょう。

この記事はほぼサーバなどを触ったことがない人物が学んだことを整理するために書いていますので間違いなどが多々あると思います。間違いなどありましたら是非コメントなどで教えていただけると幸いです。