メインコンテンツへスキップ

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 を使ってください。
タイムゾーンの扱いの詳しい説明については、MySQL のタイムスタンプとタイムゾーンを参照してください。

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 を、列にすぐ妥当な値を持たせたい「未設定」のシナリオではデフォルト値を選んでください。両者を混在させると、クエリに一貫性のなさが生じます。

トラブルシューティング

関連項目