はじめに
こんにちは。
今回は、Qiita Tech Festa 2026の投稿テーマ「MySQLについてこの一年間で新しく知ったこと」に合わせて、MySQLの BOOLEAN 型について私がこの一年間で新しく知ったことを書きます。
1年ほど前、配属されて少し経った頃に過去のDDLとテーブルの中身を眺めていたところ、DDLでは BOOLEAN と定義されているカラムに、実際のデータとして 0 や 1 が入っていることに気づきました。
不思議に思って調べたところ、MySQLの BOOLEAN 型は内部的には TINYINT(1) として扱われることを知りました。
この記事では、MySQLの BOOLEAN 型がどのように扱われるのかを、実際のSQLと公式ドキュメントを見ながら整理します。
実行環境
- MySQL 8.0.46
きっかけ: DDLではBOOLEANなのにテーブルには0/1が入っていた
たとえば、次のようなテーブルがあったとします。
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
is_active BOOLEAN
);
DDLを見ると、is_active は BOOLEAN 型として定義されており、名前だけを見ると true や false が入る型のように見えます。
しかし、実際に既存のデータを見てみると、以下のように is_active の値は 0 や 1 と表示されていました。
+----+-----------+
| id | is_active |
+----+-----------+
| 1 | 0 |
| 2 | 1 |
+----+-----------+
ここで、当時まったくのMySQL初心者だった私は、「なぜ BOOLEAN で定義されているのに true や false ではなく 0 / 1 が入っているんだ?(意味はわかるけど)」と疑問に思い、このことがMySQLの BOOLEAN 型について調べるきっかけになりました。
MySQLのBOOLEAN型とTRUE/FALSEの扱い
MySQLの公式ドキュメントでは、BOOL と BOOLEAN について以下のように説明されています。
BOOL、BOOLEAN
これらの型はTINYINT(1)のシノニムです。
つまり、MySQLでは BOOLEAN という型でカラムを定義しても、内部では TINYINT(1) として扱われることになります。
試しに先ほどのテーブルでカラムの情報を確認してみると以下のように表示され、 is_active の型は実際にはTINYINT(1)型として扱われていることがわかります。
+-----------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| is_active | tinyint(1) | YES | | NULL | |
+-----------+------------+------+-----+---------+----------------+
また、公式ドキュメントでは TRUE と FALSE についても次のように説明されています。
TRUE値とFALSE値はそれぞれ、1と0の単なるエイリアスです。
このことは次のSQLで実際に確認できます。
SELECT TRUE, FALSE;
+------+-------+
| TRUE | FALSE |
+------+-------+
| 1 | 0 |
+------+-------+
MySQLでは、上記のようにテーブルを指定せずに SELECT だけで式の評価結果を確認できます。
0と1だけが入るとは限らない
BOOLEAN は TINYINT(1) のシノニムなので、 0 と 1 以外の値を入れることができます。
たとえば、次のように 2 を入れることもできます。
INSERT INTO users (is_active)
VALUES (2);
公式ドキュメントには次のように書かれています。
ゼロの値は false と見なされます。
ゼロ以外の値は true と見なされます。
つまり、2 は TRUE と等しい(エイリアス)わけではありませんが、条件式ではtrueとして扱われます。
このことは次のSQLで実際に確認できます。
SELECT IF(0, 'true', 'false');
SELECT IF(1, 'true', 'false');
SELECT IF(2, 'true', 'false');
+------------------------+
| IF(0, 'true', 'false') |
+------------------------+
| false |
+------------------------+
+------------------------+
| IF(1, 'true', 'false') |
+------------------------+
| true |
+------------------------+
+------------------------+
| IF(2, 'true', 'false') |
+------------------------+
| true |
+------------------------+
一方で、TRUE は 1 のエイリアスですが、 2 のエイリアスではないので、2 = TRUE は成り立ちません。
SELECT 2 = TRUE, 2 = FALSE;
+----------+-----------+
| 2 = TRUE | 2 = FALSE |
+----------+-----------+
| 0 | 0 |
+----------+-----------+
もし 0 と 1 だけを許可したい場合は、MySQL 8.0.16以降に登場したCHECK 制約を使うことで制限できます。
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
is_active BOOLEAN CHECK (is_active IN (0, 1))
);
他のRDBMSではBooleanはどう扱われるのか
MySQL以外の主要なRDBMSでのBooleanの扱いについて調べました。こうして見ると、RDBMSによって扱いがかなり違うことがわかります。
| RDBMS | Booleanの扱い | メモ |
|---|---|---|
| PostgreSQL |
boolean 型が存在する |
TRUE、FALSE、NULL を扱える。出力例では t / f と表示される |
| SQL Server |
bit 型を使う |
1、0、NULL を扱える。文字列値の TRUE は 1、FALSE は 0 に変換される |
| SQLite |
BOOLEAN と書けるが、専用のBoolean型はない |
Boolean値は整数の 0 / 1 として保存される |
| Oracle |
BOOLEAN 型が存在する |
TRUE、FALSE、UNKNOWN を扱える |
まとめ
- MySQLの
BOOL/BOOLEANはTINYINT(1)のシノニム -
TRUE/FALSEは1/0のエイリアス - 条件式では0がfalse、ゼロ以外がtrue扱いになる
- ただし、
2 = TRUEになるわけではない -
0と1だけに制限したい場合は、CHECK制約などを検討する
最後までお読みいただきありがとうございました。
参考文献
- MySQL 8.0 リファレンスマニュアル - 11.1.1 数値データ型の構文
- MySQL 8.0 リファレンスマニュアル - 9.1.6 boolean リテラル
- MySQL 8.0 リファレンスマニュアル - 13.1.20.6 CHECK 制約
- PostgreSQL Documentation - 8.6. Boolean Type
- ビット (Transact-SQL) - SQL Server | Microsoft Learn
- Datatypes In SQLite - SQLite
- Oracle Database SQL Language Reference - Data Types