VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
整数型
MySQL には 5 つの整数型があります。想定される範囲に収まる最小の型を選んでください。INT UNSIGNED は正の範囲を約 43 億に倍増させます。常に正の値をとる主キーと外部キーには UNSIGNED を使ってください。追加コストなしで範囲を広げられます。
BIGINT は INT の 2 倍のストレージを使います。すべての ID にデフォルトで使ってはいけません。INT は 20 億行以上を扱えますが、ほとんどのテーブルはそこまで到達しません。
文字列型
VARCHAR と CHAR
VARCHAR(n) は、文字列に含まれるバイト数(に長さのための 1〜2 バイトを加えたもの)だけを格納します。CHAR(n) は常にちょうど n バイトを格納し、短い文字列はスペースで埋めます。
CHAR は、長さのプレフィックスを解析する必要がないため、固定長の値ではわずかに速いことがあります。長さが変わるものには VARCHAR を使ってください。
VARCHAR と TEXT
VARCHAR 値は、クラスタ化インデックスのページ内にインラインで格納されます。TEXT(および BLOB)の値は、十分に大きくなるとオーバーフローページに格納されます。これは次のことを意味します。
VARCHAR列は直接インデックスに含められるTEXT列は完全にはインデックス化できない — プレフィックス長が必要:INDEX (description(100))
VARCHAR を使ってください。インライン格納が意味をなさない長い内容(記事、コメント、HTML)には TEXT を使います。
日付と時刻の型
DATETIME と TIMESTAMP の重要な違いは次のとおりです。
TIMESTAMPは値を UTC として格納し、取得時にセッションのtime_zoneに変換します。アプリケーションが複数のタイムゾーンで動作する場合、TIMESTAMPは変換を自動的に処理します。DATETIMEはタイムゾーン変換なしでリテラル値を格納します。入れたものがそのまま出てきます。TIMESTAMPには 2038 年の上限があります(Unix タイムスタンプのオーバーフロー)。2038 年以降の日付にはDATETIMEを使ってください。
10 進数と浮動小数点
FLOAT と DOUBLE は 2 進浮動小数点を使うため、10 進の小数を正確に表現できません。浮動小数点では 0.1 + 0.2 は 0.30000000000000004 になります。金額には常に DECIMAL を使ってください。
JSON
JSON 列は検証済みの JSON を格納し、パスベースのクエリ演算子を提供します。
JSON 列には直接インデックスを作成できません。頻繁にクエリされる JSON フィールドにインデックスを作成するには、生成列を使います。
よくある質問
主キーには INT と BIGINT のどちらを使うべきですか?
INT は符号付き整数で 21 億行、符号なしで 43 億行を扱えます。ほとんどのテーブルでは INT UNSIGNED で十分です。それを本当に超えると予想される場合、または 4 バイトに収まらない UUID 形式の ID を使っている場合は BIGINT を使ってください。
考えずに済むように、どこでも VARCHAR(255) を使ってもよいですか?
可能ですが、VARCHAR の宣言が長いほどインデックスキーが広くなり、インデックスのメモリ使用量が増え、1 ページに収まるインデックスエントリの数が減ります。現実的な最大値を宣言してください。名前のフィールドなら VARCHAR(255) ではなく VARCHAR(100) です。実際のストレージコストはデータの長さに一致しますが、インデックスキーの長さは宣言したサイズで固定されます。
NULL とデフォルト値の実際の違いは何ですか?
NULL は「不明」を意味します。式を通じて伝播し、集計関数からは除外されます。0 や '' のようなデフォルト値は「明示的に空に設定された」ことを意味します。本当にデータが存在しない場合には NULL を、列にすぐ妥当な値を持たせたい「未設定」のシナリオではデフォルト値を選んでください。両者を混在させると、クエリに一貫性のなさが生じます。
トラブルシューティング
関連項目
- MySQL の正規化 — 型の決定のためのスキーマ設計の背景
- MySQL の JSON — 厳格なスキーマの柔軟な代替としての JSON 列型
- MySQL のインデックスの仕組み — データ型の選択はインデックスのサイズと効率に影響する
- 多次元の範囲クエリ — n 次元の幾何データを格納してクエリするための cube 型
- MySQL と PostgreSQL: どちらを使うべきか? — 2 つのデータベースが型などでどう異なるか
- MySQL の utf8mb4: 絵文字と完全な Unicode の格納 — 列の文字セットと 4 バイトの現実
- MySQL の本物のブール型 — true と false 以外のすべてを拒否する列型
- MySQL SELECT — これらの列を読み戻すチュートリアルのレッスン