こんにちは、かつコーチです。
前回はCREATE TABLEでテーブルを作成する方法を紹介しました。
そのときにINTやVARCHAR(100)といった記述をカラムごとに付けましたが、これがデータ型です。
データ型とは、その列にどんな種類のデータを保存できるかを決めるルールのことです。
今回は数値・文字列・日付という3つの代表的なデータ型を中心に、選び方の基準を解説します。
データ型とは?
なぜデータ型を決める必要があるのか
データベースは、列ごとに「これは数値」「これは文字列」と型を決めておくことで、データを効率よく保存し、正しく計算・比較できるようにしています。
もしすべての列を文字列型で作ってしまうと、金額の合計計算や日付の比較が正しくできなくなったり、無駄にディスク容量を消費したりします。
「その列に入る値の性質に合わせて型を選ぶ」というのが、データ型選びの基本方針です。
型を間違えるとどうなるか
以前、金額を扱う列を文字列型(VARCHAR)で作ってしまったプロジェクトに関わったことがあります。
'1000'と'999'を比較すると、数値としては1000の方が大きいのに、文字列としては'999'の方が大きいと判定されてしまい、並び替えの結果がおかしくなるというバグに遭遇しました。
型選びのミスは、こういった見えにくいバグの温床になります。
基本の書き方
数値型:整数と小数を使い分ける
数値を扱う代表的な型は次の通りです。
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
stock INT NOT NULL,
price DECIMAL(10, 2) NOT NULL,
weight FLOAT
);
| 型 | 用途 | 特徴 |
|---|---|---|
INT | 整数(在庫数、年齢など) | 約-21億〜21億の範囲 |
TINYINT | 小さい整数(フラグ、ステータス) | -128〜127(または0〜255) |
DECIMAL(全体桁数, 小数点以下桁数) | 金額など正確な小数 | 誤差が出ない固定小数点 |
FLOAT / DOUBLE | 科学計算などの小数 | 誤差が出る可能性がある浮動小数点 |
金額を扱う場合はFLOATではなくDECIMALを使うのが鉄則です。
FLOATは計算過程でわずかな誤差が生じることがあり、金額計算にはそぐいません。
文字列型:CHARとVARCHARとTEXT
文字列を扱う型にも複数の選択肢があります。
CREATE TABLE members (
id INT PRIMARY KEY AUTO_INCREMENT,
postal_code CHAR(7) NOT NULL,
name VARCHAR(100) NOT NULL,
bio TEXT
);
| 型 | 用途 | 特徴 |
|---|---|---|
CHAR(n) | 固定長文字列(郵便番号など) | 常にn文字分の領域を確保 |
VARCHAR(n) | 可変長文字列(名前、メールなど) | 実際の文字数分だけ使用、最大n文字 |
TEXT | 長文(本文、備考など) | 文字数制限が緩く、長文向け |
「郵便番号のように常に決まった桁数になる値はCHAR」「名前やメールアドレスのように長さが変わる値はVARCHAR」「ブログ本文のような長文はTEXT」という使い分けが基本です。
日付・時刻型:DATE・DATETIME・TIMESTAMP
日付や時刻を扱う型も用途によって選び分けます。
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_date DATE NOT NULL,
delivered_at DATETIME,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
| 型 | 用途 | 特徴 |
|---|---|---|
DATE | 日付のみ(生年月日、注文日) | 2026-09-01のような形式 |
DATETIME | 日付+時刻 | 2026-09-01 12:30:00のような形式 |
TIMESTAMP | 日付+時刻(更新日時によく使う) | タイムゾーンの影響を受ける、範囲がDATETIMEより狭い |
updated_atのように「更新のたびに自動で現在時刻を入れたい」場合は、TIMESTAMPにON UPDATE CURRENT_TIMESTAMPを組み合わせると便利です。
つまずきやすいポイント:VARCHARの桁数を意識しない
桁数不足でデータが切り捨てられる
❌ Before:桁数を適当に決めてしまう
CREATE TABLE members (
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(20) NOT NULL
);
一見問題なさそうですが、メールアドレスは長いものだと50文字を超えることも珍しくありません。
実際に私がこの設定でテストしたとき、長めのメールアドレスを登録しようとしたらData too long for column 'email'というエラーが発生し、テーブルを作り直す羽目になりました。
✅ After:余裕を持った桁数を設定する
CREATE TABLE members (
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) NOT NULL
);
メールアドレスはVARCHAR(255)とするのが一般的な慣習です。
「よく分からない場合はまず一般的に使われる桁数に合わせる」という判断も、実務では十分有効な戦略です。
応用:ENUM型と真偽値の扱い
選択肢が決まっている値にはENUMを使う
ステータスのように、あらかじめ値の候補が決まっている列にはENUM型が便利です。
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
status ENUM('未処理', '発送済み', 'キャンセル') NOT NULL DEFAULT '未処理'
);
ENUMを使うと、指定した候補以外の値が入らないよう自動でチェックしてくれます。
ただし選択肢が頻繁に増減するような値は、ENUMではなく別のマスタテーブルに切り出す方が保守性は高くなります。
真偽値はTINYINT(1)またはBOOLEANで表現する
MySQLには専用の真偽値型がなく、BOOLEANは内部的にTINYINT(1)のエイリアスとして扱われます。
CREATE TABLE members (
id INT PRIMARY KEY AUTO_INCREMENT,
is_active BOOLEAN NOT NULL DEFAULT TRUE
);
0を偽、1を真として扱うため、フラグ管理の列にはこの形がよく使われます。
まとめ
この記事のポイント
- 数値型は整数の
INT、金額など正確な小数のDECIMALを基本に使い分ける - 文字列型は固定長の
CHAR、可変長のVARCHAR、長文のTEXTを用途で選ぶ - 日付・時刻型は
DATE・DATETIME・TIMESTAMPを使い分ける - VARCHARの桁数は余裕を持たせて設定する
- 選択肢が決まった値には
ENUM、真偽値にはBOOLEAN(TINYINT(1))が使える
次に読むべき記事
データ型を理解したら、次はテーブル同士を関連付ける主キー・外部キーの仕組みを見ていきましょう。
→ 次の記事:主キー・外部キーの役割と設定方法
タグ: SQL, 初心者向け, DDL