はじめに
SQLiteは、データの型(データ型)の扱いがほかのデータベースとはちょっと違うことをつい最近知りました。今回は、そんなSQLiteのデータ型について調べてことをアウトプットしたいと思います
👇参考サイト
1. SQLiteのデータ型は、いい意味で「ゆるい」?
多くのデータベース(MySQLやPostgreSQLなど)は、カラムごとにデータの型が決まっていて、それ以外の型のデータは入れられないようになっています(これを「静的型付け」といいます)。
ですが、SQLiteは「動的型付け」 という方法を採用しています。つまり、カラムの型はあくまで「おすすめ」 であり、実際にはどんなデータ型でも入れることができるという事実。
例えば、通常のデータベースではエラーが発生:
CREATE TABLE users(id INTEGER, name TEXT);
INSERT INTO users(id, name) VALUES ('abc', 123); -- エラー!
「id」は整数型(INTEGER)なので、文字列('abc')を入れようとするとエラーになります。
でも、SQLiteならエラーは発生しない?!:
CREATE TABLE users(id INTEGER, name TEXT);
INSERT INTO users(id, name) VALUES ('abc', 123); -- エラーにならない!
「id」は本来INTEGER型のカラムですが、文字列('abc')を入れることができてしまいます。SQLiteはカラムの型を強制しないので、柔軟にデータを扱えるのが特徴です。扱いには注意が必要です‼
2. SQLiteのデータ型(ストレージクラス)
SQLiteのデータ型は5つだけです。
私自身調べる前はENUM型を使えるものだと思っていました💦
ストレージクラス | 説明 |
---|---|
NULL | 値が空(NULL)のとき |
INTEGER | 整数(0, 1, -5, 100 など) |
REAL | 小数(3.14, -2.718, 1.5e10 など) |
TEXT | 文字列('Hello', '123' など) |
BLOB | そのままのデータ(画像やファイルなど) |
たとえば、「年齢(age)」というカラム。本来は整数(INTEGER)を入れるべきですが、SQLiteでは文字列でも保存できてしまいます。
CREATE TABLE users(age INTEGER);
INSERT INTO users(age) VALUES ('25'); -- エラーにならない!
このように、SQLiteはデータ型に対して、いい意味で柔軟に対応してくれます。
3. SQLiteには「型の傾向(型親和性)」がある
SQLiteはカラムの型を強制しませんが、カラムごとに「どんな型をおすすめするか」という設定があります。これを 型親和性(Type Affinity) といいます。
SQLiteの型親和性は以下の5種類です。
型親和性 | 説明 |
---|---|
TEXT | 基本は文字列として保存される |
NUMERIC | 数値か文字列として保存される(基本は数値) |
INTEGER | 数値として保存される(整数を優先) |
REAL | 小数として保存される |
BLOB | そのままのデータとして保存される(変換なし) |
たとえば、次のようにカラムを作ったとします。
CREATE TABLE test(a TEXT, b NUMERIC, c INTEGER, d REAL, e BLOB);
この場合、それぞれのカラムの動作は次のようになります。
INSERT INTO test(a, b, c, d, e) VALUES (123, '456', '3.14', 500, X'1234');
カラム | 保存される値 | 説明 |
---|---|---|
a (TEXT) | '123' | 123 は文字列として保存される |
b (NUMERIC) | 456 | '456' は数値に変換される |
c (INTEGER) | 3 | '3.14' は整数部分だけ保存される |
d (REAL) | 500.0 | 500 は小数として保存される |
e (BLOB) | X'1234' | そのまま保存される |
このように、型親和性によってデータが変換されることがあります。
4. SQLiteの「日付・時刻」データ型
SQLiteには 日付・時刻専用の型はありません‼
その代わり、3つの方法で保存できます。
形式 | 例 | 説明 |
---|---|---|
TEXT | '2025-01-29 12:34:56' | ISO8601形式(YYYY-MM-DD HH:MM:SS) |
REAL | 2459580.023 | ユリウス日(過去の天文学的な日付表現) |
INTEGER | 1706530496 | Unix時間(1970年1月1日からの秒数) |
たとえば、現在の日付をTEXTで保存する場合はこう書きます。
INSERT INTO logs(created_at) VALUES (DATETIME('now'));
DATETIME('now')
を使うと、現在の日付が "YYYY-MM-DD HH:MM:SS"
形式で保存されます。
まとめ
- SQLiteは「動的型付け」なので、カラムの型に関係なくどんなデータでも入れられてしまうかもしれない
- ストレージクラス(基本のデータ型)は5つ:NULL, INTEGER, REAL, TEXT, BLOB
- カラムごとに「型の傾向(型親和性)」があり、データが自動変換されることがある
- 日付・時刻型もないが、TEXT・REAL・INTEGERの3種類で保存できる
SQLiteは柔軟にデータを扱えるので、カラムの型にとらわれすぎず、使いやすい形でデータを保存できる反面、使用しづらさもあるのかな?と感じました💦
MYSQLと名前が似ているから同じものだと思い込んでの使用は危険だな、とも感じました。
今回の記事が何か参考になれば幸いです。