SQLデータ型 比較早見表|MySQL・PostgreSQL・SQL Server・SQLite
主要RDBMS4種(MySQL・PostgreSQL・SQL Server・SQLite)のデータ型を横断比較。整数型のバイト数と範囲、DECIMALとFLOATの使い分け、VARCHAR/TEXTの上限、DATETIME/TIMESTAMPのタイムゾーン挙動、BOOLEAN・バイナリ・JSONの対応差、そしてDB間移行のハマりどころまで、テーブル設計と移行作業で必要な確定値を一覧表示します。
📌 まずこれだけ|最頻出の確定値
| 知りたいこと | 答え |
|---|---|
| INT の範囲 | -2,147,483,648 〜 2,147,483,647(4バイト・約±21億) |
| BIGINT の範囲 | -9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807(8バイト) |
| 金額を入れる型 | DECIMAL / NUMERIC(FLOAT・DOUBLEは丸め誤差が出るため不可) |
| MySQL TIMESTAMP の上限 | 2038-01-19 03:14:07 UTC(2038年問題。以降はDATETIMEを使用) |
| MySQL の BOOLEAN | TINYINT(1) の別名(TRUE=1 / FALSE=0) |
| SQL Server の timestamp | 日時型ではない(rowversionの旧称。日時は datetime2) |
このページについて
SQLの型名はISO/IEC 9075(SQL標準)で大枠が決まっていますが、サイズ・上限・内部表現はRDBMSごとに異なります。本ページではMySQL・PostgreSQL・SQL Server・SQLiteの公式リファレンスで確認できる確定値のみを、整数・小数・文字列・日付時刻・その他(真偽値/バイナリ/JSON)の5分類で比較します。
「INTはいくつまで入る?」「金額はDECIMALとFLOATどっち?」「PostgreSQLにTINYINTはある?」「移行したらTIMESTAMPが壊れた」といった、テーブル設計・DB移行・ORM設定で頻発する疑問に即答できる構成です。
型名や数値の一部を入力すると、下の比較表(5表)の行が絞り込まれます。空欄に戻すと全行表示されます。
1. 整数型の比較
範囲は符号付きの値。SQLiteのINTEGERは値の大きさに応じて1〜8バイトで可変格納され、最大8バイト符号付き整数(BIGINT相当)まで扱えます。
| 型 | バイト数 | 範囲(符号付き) | MySQL | PostgreSQL | SQL Server | SQLite |
|---|---|---|---|---|---|---|
| TINYINT | 1 | -128 〜 127 | ○ | ×(SMALLINTで代用) | △ 0〜255の符号なしのみ | INTEGERで代用 |
| SMALLINT | 2 | -32,768 〜 32,767 | ○ | ○ | ○ | INTEGERで代用 |
| MEDIUMINT | 3 | -8,388,608 〜 8,388,607 | ○ | × | × | INTEGERで代用 |
| INT / INTEGER | 4 | -2,147,483,648 〜 2,147,483,647 | ○ | ○ | ○ | INTEGER(最大8バイト) |
| BIGINT | 8 | -9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807 | ○ | ○ | ○ | INTEGERで対応 |
UNSIGNED(符号なし)修飾はMySQL固有です(例: INT UNSIGNED = 0〜4,294,967,295)。PostgreSQLに符号なし整数型はなく、SQL ServerのTINYINTは符号なし(0〜255)しかありません。
2. 小数型の比較
DECIMAL/NUMERICは10進の正確値、FLOAT/DOUBLE/REALは2進の近似値(IEEE 754)。金額・数量などの業務データはDECIMALを使います。
| 型 | 性質 | MySQL | PostgreSQL | SQL Server | SQLite |
|---|---|---|---|---|---|
| DECIMAL / NUMERIC | 10進・正確 | 最大65桁(小数部は最大30桁) | 整数部131,072桁・小数部16,383桁まで | 最大38桁 | 専用型なし(NUMERIC親和性で近似格納) |
| 単精度浮動小数(4バイト) | 2進・近似 | FLOAT | real(精度6桁程度) | real(=float(24)) | ×(REALは8バイト) |
| 倍精度浮動小数(8バイト) | 2進・近似 | DOUBLE | double precision(精度15桁程度) | float(53) | REAL |
| 通貨専用型 | — | ×(DECIMALを使用) | money(8バイト) | money / smallmoney | × |
通貨専用型よりも、桁数を明示できるDECIMAL(例: DECIMAL(10,2))での設計が一般的です。
3. 文字列型の比較
上限の単位に注意。MySQLとSQL Serverはバイト数基準の制限があり、PostgreSQLのvarchar(n)のnは文字数です。
| 型 | MySQL | PostgreSQL | SQL Server | SQLite |
|---|---|---|---|---|
| CHAR(固定長) | 最大255文字 | character(n)。1フィールド約1GBまで | char(n)は最大8,000バイト | TEXT扱い(固定長なし) |
| VARCHAR(可変長) | 最大65,535バイト(行全体の上限65,535バイトと共有) | varchar(n)のnは文字数。1フィールド約1GBまで | varchar(n)は最大8,000バイト。varchar(max)は最大2GB(2³¹-1バイト) | TEXT扱い(長さ指定は無視) |
| TEXT(長文) | TINYTEXT 255B / TEXT 65,535B / MEDIUMTEXT 16MB / LONGTEXT 4GB | text(長さ上限の指定なし・約1GBまで) | varchar(max)を使用(text型は旧式) | TEXT(既定の上限は10億バイト) |
| Unicode専用型 | 不要(列ごとに文字セット指定) | 不要(UTF-8データベースで対応) | nchar(n)/nvarchar(n)は最大4,000文字。nvarchar(max)は最大2GB | 不要(TEXTはUTF-8/UTF-16) |
MySQLのVARCHAR(n)のnは文字数指定ですが、格納上限はバイト数で決まるため、utf8mb4(1文字最大4バイト)では実質約16,383文字が上限になります。
4. 日付時刻型の比較
SQLiteに日付時刻の専用型はなく、TEXT(ISO 8601)・REAL(ユリウス日)・INTEGER(Unix時間)のいずれかで格納し日付関数で操作します。
| 型 | MySQL | PostgreSQL | SQL Server | SQLite |
|---|---|---|---|---|
| DATE | 1000-01-01 〜 9999-12-31 | 紀元前4713年 〜 西暦5874897年 | 0001-01-01 〜 9999-12-31 | 専用型なし |
| TIME | -838:59:59 〜 838:59:59(経過時間も表現可) | 00:00:00 〜 24:00:00 | 00:00:00.0000000 〜 23:59:59.9999999 | 専用型なし |
| DATETIME(TZなし) | DATETIME: 1000-01-01 00:00:00 〜 9999-12-31 23:59:59 | timestamp: 紀元前4713年 〜 西暦294276年 | datetime: 1753年〜9999年(精度約3.33ms) / datetime2: 0001年〜9999年(精度100ns) | 専用型なし |
| TIMESTAMP | 1970-01-01 00:00:01 UTC 〜 2038-01-19 03:14:07 UTC。UTCで保存しセッションTZで表示 | timestampはTZなし型(TZ付きは下段) | 日時型ではない(rowversionの旧称) | 専用型なし |
| タイムゾーン付き日時 | ×(TIMESTAMPの自動変換のみ) | timestamptz: UTCで保存し表示時に変換 | datetimeoffset: UTCオフセットを値ごとに保持 | 専用型なし |
5. 真偽値・バイナリ・JSON型の比較
| 型 | MySQL | PostgreSQL | SQL Server | SQLite |
|---|---|---|---|---|
| BOOLEAN | TINYINT(1)の別名(TRUE=1/FALSE=0) | boolean(1バイト・真の論理型) | bit(0・1・NULL) | 専用型なし(INTEGERの0/1) |
| バイナリ | BINARY(最大255B)/VARBINARY、BLOB系(TINYBLOB 255B〜LONGBLOB 4GB) | bytea(約1GBまで) | binary/varbinary(n)は最大8,000バイト。varbinary(max)は最大2GB | BLOB |
| JSON | JSON型あり(5.7.8以降・バイナリ形式で格納) | json(テキスト保持)とjsonb(バイナリ・インデックス可)の2種 | 専用型なし(nvarcharに格納しJSON関数で操作・2016以降) | 専用型なし(TEXT+JSON関数。3.38.0以降は標準組込) |
| UUID | 専用型なし(BINARY(16)やCHAR(36)で代用) | uuid型あり | uniqueidentifier型あり | 専用型なし |
6. DB間移行のハマりどころ
| 落とし穴 | 何が起きるか | 対策 |
|---|---|---|
| TINYINT(1)とBOOLEAN | MySQLのBOOLEANは実体がTINYINT(1)。0/1以外も格納でき、PostgreSQLの真のboolean型へ移行すると2以上の値が変換エラーや意図しない真偽値になる | 移行前に0/1以外の値を洗い出す。ドライバのtinyint→boolean自動変換設定も確認 |
| TIMESTAMPの2038年問題 | MySQLのTIMESTAMPは2038-01-19 03:14:07 UTCが上限。契約満了日など未来日付が入らない | 未来日時を扱う列はDATETIMEにする。既存列は計画的に型変更 |
| SQL Serverのtimestamp | 名前に反して日時型ではなくrowversion(更新順のバイナリ値)。日時のつもりでSELECTすると16進値が返る | 日時にはdatetime2/datetimeoffsetを使用。移行ツールのマッピング定義を確認 |
| SQLiteの動的型 | 列の型宣言は「型親和性」の判定にしか使われず、どの列にも任意の型の値が入る。長さ制限も無視される | アプリ側でバリデーションする。SQLite 3.37.0以降ならSTRICTテーブルで型を強制 |
| UNSIGNEDはMySQL固有 | INT UNSIGNED(上限約42.9億)をPostgreSQLのintegerへ移すと上限超過の恐れ | 符号なし列はBIGINTなど1段大きい型へマッピング |
| VARCHAR(n)のnの意味 | PostgreSQLは文字数、SQL Serverのvarcharはバイト数。マルチバイト文字で「同じn」でも入る文字数が違う | 日本語データはSQL Serverではnvarcharを使うか、バイト数換算で長さを再設計 |
使い方・選び方のポイント
使用場面
テーブル設計(CREATE TABLE)・DB移行・ORMのスキーマ定義・レビュー時の型チェックに使います。迷ったら「格納したい値の範囲と性質(正確値か近似値か)」から逆引きします。
よくある間違い
①金額にFLOAT/DOUBLEを使う(丸め誤差が蓄積)②連番IDをINTにして約21億で枯渇 ③MySQLのTIMESTAMP列に2038年以降の日付を入れようとする ④SQL Serverのtimestampを日時型と誤解 ⑤SQLiteで型宣言や長さ指定が強制されると思い込む、が定番です。
選び方のコツ
①整数は範囲で選ぶ(迷ったらINT、大規模テーブルの主キーはBIGINT)②金額・数量など正確さが必要な数値はDECIMAL、科学計算はDOUBLE ③文字列は上限を見積もってVARCHAR、長文はTEXT系 ④日時はタイムゾーン要件で選ぶ(複数TZならPostgreSQLはtimestamptz、SQL Serverはdatetimeoffset)。
よくある質問
Q1. 金額を保存するのに最適な型は?
A. DECIMAL(NUMERIC)型です。10進数を正確に保持するため丸め誤差が出ません。FLOATやDOUBLEは2進浮動小数点のため0.1のような値を正確に表現できず、金額計算に使うと誤差が蓄積します。例えば税込計算はDECIMAL(10,2)のように小数部の桁数を明示して行います。
Q2. INTとBIGINTはどちらを使うべき?
A. INTの上限は2,147,483,647(約21億)です。連番IDが21億件を超える可能性のあるテーブル(ログ・取引履歴など)は最初からBIGINT(上限約922京)にします。運用途中でINTからBIGINTへ変更する作業は、大規模テーブルでは長時間ロックの原因になります。
Q3. MySQLのDATETIMEとTIMESTAMPの違いは?
A. DATETIMEは書き込んだ値をそのまま保存し(範囲は1000年〜9999年)、TIMESTAMPはUTCに変換して保存しセッションのタイムゾーンに変換して表示します。TIMESTAMPの上限は2038-01-19 03:14:07 UTC(2038年問題)のため、それ以降の日時を扱う列にはDATETIMEを使います。
Q4. MySQLにBOOLEAN型はある?
A. BOOLEAN(BOOL)はTINYINT(1)の別名で、独立した型ではありません。TRUEは1、FALSEは0として格納されます。0と1以外の値も格納できてしまう点がPostgreSQLの真のboolean型との違いで、DB間移行やORM設定での注意点です。
Q5. SQL ServerのTIMESTAMP型に日時は保存できる?
A. できません。SQL Serverのtimestampはrowversion(行の更新順を示すバイナリ値)の旧称で、日付時刻型ではありません。日時にはdatetime2やdatetimeoffsetを使います。MySQLやPostgreSQLから移行するときの代表的な落とし穴です。
Q6. SQLiteでVARCHAR(50)と書いたら50文字に制限される?
A. 制限されません。SQLiteは動的型で、列の型宣言は型親和性(TEXT/INTEGERなど)の判定に使われるだけで、長さ指定は無視されます。列に型を厳密に強制したい場合は、SQLite 3.37.0以降で使えるSTRICTテーブルを利用します。
Q7. VARCHAR(255)がよく使われるのはなぜ?
A. MySQLでは長さ255バイト以下のVARCHAR値は長さ情報を1バイトで格納でき、それを超えると2バイト必要になる境界が255だからです。歴史的な慣習として広まりましたが、現在は用途に必要な長さを見積もって指定するのが基本です。
なぜ同じ「SQL」なのに型が違うのか
SQLの型体系はISO/IEC 9075(SQL標準)がINTEGER・NUMERIC・CHARACTER VARYINGといった型の枠組みを定義していますが、バイト数・上限値・内部表現は「実装定義」とされている部分が多く、各RDBMSが独自に決めています。MySQLのMEDIUMINT(3バイト)やUNSIGNED修飾、PostgreSQLのjsonb、SQL Serverのdatetimeoffsetは、それぞれの製品が歴史的に積み上げてきた方言です。同じ「INTEGER」という宣言でも中身が同一とは限らない、というのがDB移行の難しさの根源です。
数値型の分類で重要なのが正確値(exact numeric)と近似値(approximate numeric)の区別です。DECIMALは10進の桁をそのまま保持するため「0.1 + 0.2 = 0.3」が正確に成り立ちますが、FLOAT/DOUBLEはIEEE 754の2進浮動小数点であり、0.1は2進数では循環小数になるため厳密には表現できません。1回の計算では誤差が見えなくても、集計や乗算を繰り返すと差が現れるため、会計・在庫のような業務データは正確値の型で持つのが原則です。
SQLiteだけが大きく異なるのは、型を列ではなく値そのものに持たせる動的型(manifest typing)を採用しているためです。格納クラスはNULL・INTEGER・REAL・TEXT・BLOBの5種のみで、列の型宣言は「型親和性」というゆるやかな変換ヒントとして扱われます。組込み用途で軽量・柔軟であることを優先した設計ですが、サーバー型RDBMSと同じ感覚でスキーマに型チェックを期待すると裏切られるため、3.37.0で追加されたSTRICTテーブルやアプリ側の検証で補います。
関連する早見表
- 正規表現早見表 — 入力値バリデーションのパターン
- データ容量換算早見表 — バイト・KB・MB・GBの換算
- ASCIIコード早見表 — 文字コードの基礎
- HTTPステータスコード早見表 — API開発のレスポンス設計
- Linuxコマンド早見表 — DBサーバーの運用・調査
関連規格・出典
- MySQL リファレンスマニュアル「Data Types」— 整数・DECIMAL・文字列・日付時刻型の範囲と上限
- PostgreSQL 公式ドキュメント「Chapter 8. Data Types」— numeric・文字型・日付時刻型・jsonb
- SQL Server Transact-SQL リファレンス「データ型」— int/bigint・decimal・varchar(max)・datetime2・rowversion
- SQLite 公式ドキュメント「Datatypes In SQLite」「STRICT Tables」— 型親和性・格納クラス
- ISO/IEC 9075(SQL標準)— 型体系の枠組み(参考)
最終更新: 2026-07-02