データ型

データ型

収納ボックスにはさまざまなサイズがあるように — 耳飾り用の小さな仕切り、腕時計用の中サイズ、マフラー用の大サイズ — データベースの各列にもデータに合った「ボックス」が必要です。適切な型を選択すれば、データは安全で省スペースになります。間違えれば、ストレージの浪費や精度の低下につながります。


1. 基本概念

概念 説明
数値型 整数と小数を格納。INT、BIGINT、DECIMAL、FLOATなど
文字列型 テキストデータを格納。CHAR、VARCHAR、TEXT
日付型 日付と時刻を格納。DATE、DATETIME、TIMESTAMP
ブール型 真/偽の値を格納。SQLiteはINTEGER(0/1)を使用
NULL 「不明」または「欠損」を表す — 空文字列でもゼロでもない
型選択の原則 データ範囲、精度要件、ストレージ効率に基づいて最適な型を選択

2. 基本構文

数値型

説明 範囲/精度 最適な用途
INTEGER / INT 整数 ±21億 ID、数量、年齢
BIGINT 大きな整数 ±9.2×10¹⁸ 大量データのID、ファイルサイズ
DECIMAL(p,s) / NUMERIC(p,s) 正確な小数 p = 全桁数、s = 小数桁数 金額、価格(精度低下なし)
FLOAT / REAL 浮動小数点 有効桁数約7桁 科学計算、近似値
DOUBLE 倍精度浮動小数点 有効桁数約15桁 高精度の近似計算
SQL
-- DECIMALで正確な金額を保存
CREATE TABLE accounts (
    id INTEGER PRIMARY KEY,
    balance DECIMAL(12, 2)  -- 最大12桁、小数2桁
);

-- FLOATで近似的に保存
CREATE TABLE measurements (
    id INTEGER PRIMARY KEY,
    temperature REAL  -- 近似値、小さな誤差がある可能性
);
💡 ヒント: 金額には必ずDECIMALを使用し、絶対にFLOATを使わないでください! FLOATは近似値を保存します — 0.1 + 0.20.30000000000000004になる可能性があり、金融シナリオでは致命的です。

文字列型

説明 最大長 最適な用途
CHAR(n) 固定長文字列 255バイト 固定長データ(例:性別M/F、ステータスコード)
VARCHAR(n) 可変長文字列 65535バイト 名前、メールアドレス、タイトル
TEXT 長いテキスト 無制限 記事本文、メモ、説明
SQL
CREATE TABLE articles (
    id INTEGER PRIMARY KEY,
    title VARCHAR(200),    -- タイトル、最大200文字
    status CHAR(1),         -- ステータス:D=下書き、P=公開済み
    content TEXT             -- 本文、無制限
);
💡 ヒント: SQLiteは文字列型に対して寛容です — 実際には任意の長さの文字列を格納できます。ただし、コードの可読性とデータベース間の互換性のため、型を正しく宣言することを推奨します。

日付型

説明 形式 最適な用途
DATE 日付 YYYY-MM-DD 誕生日、入社日
DATETIME 日付と時刻 YYYY-MM-DD HH:MM:SS 作成時刻、予約時間
TIMESTAMP タイムスタンプ 自動管理 レコード更新時刻、タイムゾーンをまたぐシナリオ
SQL
CREATE TABLE events (
    id INTEGER PRIMARY KEY,
    event_name TEXT,
    event_date DATE,              -- 日付のみ
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP  -- 作成時刻を自動記録
);
💡 ヒント: SQLiteには専用の日付型がありません。日付は通常TEXT(ISO 8601形式、例:'2024-01-15')またはINTEGER(Unixタイムスタンプ)として保存されます。SQLiteの組み込み日付関数(DATE()DATETIME()など)はこれらの形式を正しく処理できます。

ブール型

説明 保存方法
BOOLEAN 真/偽 SQLiteではINTEGERとして保存:0=偽、1=真
BIT ビット値 MySQL/SQL Serverで使用
SQL
CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT,
    is_active BOOLEAN DEFAULT 1  -- 1=有効、0=無効
);

-- ブール値を挿入
INSERT INTO users (name, is_active) VALUES ('John', TRUE);   -- 1として保存
INSERT INTO users (name, is_active) VALUES ('Jane', FALSE);  -- 0として保存

-- ブール値でクエリ
SELECT * FROM users WHERE is_active = 1;
💡 ヒント: SQLiteでは、TRUEは1に、FALSEは0に等しいです。ただし、コードの可読性のため、数字を直接書く代わりにTRUE/FALSEを使用することを推奨します。

NULLの意味

NULLは「不明」または「欠損」を表します — 空文字列''ではなく、数値0ではなく、もちろんFALSEでもありません。

SQL
-- NULLを含むすべての演算の結果はNULL
SELECT NULL + 1;        -- 結果:NULL
SELECT NULL || 'hello'; -- 結果:NULL

-- NULLを確認するには、IS / IS NOTを使用
SELECT * FROM employees WHERE department_id IS NULL;     -- ✅ 正しい
SELECT * FROM employees WHERE department_id = NULL;      -- ❌ 常に空を返す
SELECT * FROM employees WHERE department_id IS NOT NULL; -- ✅ 正しい
💡 ヒント: NULLは初心者にとって最大の落とし穴です。2つのルールを覚えてください:①NULLの確認にはISを使用し、=は使わない; ②NULLを含むすべての演算の結果はNULLになる

型選択のベストプラクティス

シナリオ 推奨型 理由
主キーID INTEGER PRIMARY KEY AUTOINCREMENT 整数は文字列より高速。自動採番が便利
金額/価格 DECIMAL(10,2) 正確な保存、丸め誤差なし
ユーザー名/タイトル VARCHAR(100) 可変長でスペース節約。長さ制限で悪用を防止
記事本文 TEXT 無制限の長さ、大きなテキストに適している
日付 DATE / DATETIME 明確なセマンティクス、組み込み日付関数のサポート
はい/いいえフラグ BOOLEAN 明確なセマンティクス、コンパクトな保存
列挙ステータス CHAR(1) または INTEGER ENUM型より柔軟

3. コード例

例:商品テーブルの作成と型制約の確認(難易度⭐)

商品テーブルを作成して、さまざまなデータ型の動作を体験します。

SQL
-- 指定された列型で商品テーブルを作成
CREATE TABLE products_demo (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(100) NOT NULL,
    price DECIMAL(10, 2) NOT NULL,
    stock INTEGER DEFAULT 0,
    description TEXT,
    is_active BOOLEAN DEFAULT 1,
    created_at DATE
);

-- さまざまな型のデータを挿入
INSERT INTO products_demo (name, price, stock, description, is_active, created_at)
VALUES ('メカニカルキーボード', 299.50, 100, 'ブルースイッチ87キー、タイピングに最適', TRUE, '2024-01-15');

INSERT INTO products_demo (name, price, stock, description, is_active, created_at)
VALUES ('ワイヤレスマウス', 89.00, 200, NULL, TRUE, '2024-02-20');

-- データと型の動作を確認
SELECT name, price, stock, description, is_active, created_at
FROM products_demo;
▶ 試してみよう

出力

TEXT
name              price    stock  description                                   is_active  created_at
----------------  -------  -----  ---------------------------------------------  ---------  ----------
メカニカルキーボード 299.50 100    ブルースイッチ87キー、タイピングに...       1          2024-01-15
ワイヤレスマウス    89.00    200    (NULL)                                         1          2024-02-20

例:NULLの算術特性を確認(難易度⭐⭐)

実際のクエリを通じてNULLの特別な動作を理解します。

SQL
-- テストテーブルを作成
CREATE TABLE null_test (
    id INTEGER PRIMARY KEY,
    value INTEGER
);

INSERT INTO null_test VALUES (1, 10);
INSERT INTO null_test VALUES (2, NULL);
INSERT INTO null_test VALUES (3, 20);

-- 算術演算でのNULL
SELECT id, value, value + 100 AS add_result
FROM null_test;
▶ 試してみよう

出力

TEXT
id  value  add_result
--  -----  ----------
1   10     110
2   (NULL) (NULL)
3   20     120
SQL
-- NULLの確認:IS vs =
SELECT id, value,
    CASE WHEN value IS NULL THEN 'NULLです' ELSE 'NULLではありません' END AS check_result
FROM null_test;

出力

TEXT
id  value  check_result
--  -----  ------------
1   10     NULLではありません
2   (NULL) NULLです
3   20     NULLではありません
SQL
-- NULLと集計関数:COUNTはNULLを除外、SUM/AVGはNULLを無視
SELECT COUNT(value) AS count_val,      -- 2(NULLをカウントしない)
       COUNT(*) AS count_all,          -- 3(すべての行をカウント)
       SUM(value) AS sum_val,          -- 30(NULLを無視)
       AVG(value) AS avg_val           -- 15(30/2、30/3ではない)
FROM null_test;

出力

TEXT
count_val  count_all  sum_val  avg_val
---------  ---------  -------  -------
2          3          30       15.0

4. 主な応用シナリオ

シナリオ1:ユーザー登録テーブルの設計

ビジネス要件に基づいて適切な型を選択します:

SQL
CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,     -- ユーザー名、一意でNULL不可
    email VARCHAR(100) NOT NULL UNIQUE,       -- メールアドレス
    password_hash CHAR(64) NOT NULL,          -- SHA256ハッシュ、固定64文字
    age INTEGER CHECK (age >= 0 AND age <= 150),  -- 年齢、妥当な範囲チェック
    balance DECIMAL(12, 2) DEFAULT 0.00,      -- 口座残高、セントまで正確
    bio TEXT,                                  -- 自己紹介、無制限
    is_verified BOOLEAN DEFAULT 0,            // メール認証済みかどうか
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

シナリオ2:デフォルト値でのNULL処理

COALESCE関数を使用してNULLにデフォルト値を提供します:

SQL
-- 従業員情報をクエリし、部署がNULLの場合は「未割り当て」と表示
SELECT e.name,
       COALESCE(d.name, '未割り当て') AS department,
       COALESCE(e.salary, 0) AS salary
FROM employees e
LEFT JOIN departments d ON e.department_id = d.id;

❓ よくある質問

質問:DECIMAL(10,2)とFLOATの両方で小数を保存できます。違いは何ですか? 回答: DECIMALは正確な値を保存し、金額など精度が重要なシナリオに適しています。FLOATは近似値を保存し、計算は速いものの小さな誤差があります。シンプルなルール:金額にはDECIMAL、科学計算にはFLOATを使用します。

質問:CHARとVARCHARのどちらを選べばいいですか? 回答: データ長が固定の場合(例:性別M/F、MD5ハッシュ)、CHARの方が効率的です。長さが異なる場合(例:名前、タイトル)、VARCHARがよりスペースを節約します。実際にはVARCHARがより多く使用されます。

質問:NULLと空文字列''の違いは何ですか? 回答: NULLは「不明/値なし」を意味し、空文字列は「値は既知で空である」を意味します。例えば、「ミドルネーム」列:外国人にはミドルネームがない場合(NULL)、中国人にはあるが空文字列('')の場合があります。集計関数では、COUNT(列)はNULLをカウントしませんが、空文字列はカウントします。

質問:SQLiteの型システムは他のデータベースとどう違いますか? 回答: SQLiteは動的型システムを使用しています — 列の型宣言は厳密な制約というより「提案」に近いです。INTEGER列に文字列を挿入できます(非推奨ですが)。MySQL、PostgreSQLなどは厳密な型システムを使用しており、型の不一致はエラーを引き起こします。コードの移植性のため、型を正しく使用してください。


📖 まとめ


📝 演習

演習1(⭐)

以下のフィールドを持つ「図書館貸出」テーブルを設計し、適切なデータ型を選択してください:

演習2(⭐⭐)

演習1のテーブルを作成し、5件のレコードを挿入してから、クエリを書いてください:

  1. 未返却の貸出レコードをすべてクエリ
  2. 備考がNULLのレコードをクエリ
  3. 未返却レコードの総数をカウント(NULL処理に注意)

次のレッスン

👉 06-演習:基本クエリ総合演習

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%