VARCHARとは?基本定義からデータベース別の挙動と設計ポイントまで徹底解説

VARCHAR型とは — 基本定義と概観

VARCHAR(Variable Characterの略)は「可変長文字列」を表すデータ型で、リレーショナルデータベースで広く使われます。あらかじめ最大長を指定しておき、その長さまでの文字列を格納できます。固定長のCHAR型と対比され、実際のデータ長に応じて記憶領域が変動するため、省メモリで扱えるのが特徴です。

SQL標準と一般的な性質

  • 可変長:保存されるのは実際の文字数(またはバイト数)で、余分な空白でパディングされない。
  • 最大長の指定:VARCHAR(n) のように n を指定する。標準では n は「文字数」を意味しますが、実装によっては内部でバイト単位で管理される場合がある(文字セットに依存)。
  • 長さメタ情報:可変長であるため、長さを示すメタデータ(多くの場合 1〜2 バイト程度)が付与される。
  • 用途:名前、メールアドレス、ステータスなど、長さが大きく変動するが極端に長くないテキスト向け。

主要データベースごとの挙動(要点)

MySQL / MariaDB

MySQLでは、VARCHARは可変長文字列を格納します。重要点は以下の通りです。

  • MySQL 5.0.3以前は最大255文字だったが、それ以降は内部的に行全体のサイズ制限(最大 65,535 バイト)に依存するようになった。
  • VARCHAR 列は長さに応じて 1 バイトまたは 2 バイトの長さプレフィックスを持つ(最大長 ≤ 255 の場合は1バイト、それ以上は2バイト)。
  • 文字セット(例:utf8mb4)を使うと1文字あたり最大で複数バイトになるため、指定した n が「文字数」なのか「バイト数」なのかで実効最大値が変わる。たとえば utf8mb4 を使うと最大バイト数は文字数×最大バイト数となる。
  • InnoDBでは大きなVARCHARはオフページ(行外)に格納される場合があり、行の格納方式やROW_FORMATにより挙動が変わる。

PostgreSQL

  • PostgreSQLでは character varying(n)(= VARCHAR(n))と制限無しの varchar は存在する。length制限は文字数ベースで扱われる。
  • 実質的なフィールドサイズの上限は非常に大きく(理論上最大1GB程度、内部ではTOASTにより大きな値を外部格納できる)、通常のアプリケーションで上限に悩むことは稀。
  • 内部は可変長(varlena)形式で管理され、必要に応じて外部化(TOAST)される。

SQL Server (Microsoft)

  • varchar(n) は n の最大が 8000(文字)で、より大きな文字列は varchar(max) を使う(最大で約2GB相当)。
  • SQL Server の varchar は Unicode を扱わない(Unicode は nvarchar を使用、2バイト/文字)。
  • varchar(max) は内部的にオンページ・オフページの扱いがあり、大きなデータはオフページに格納されパフォーマンスに影響する場合がある。

SQLite

  • SQLite は型付けが緩やかで、CREATE TABLE で VARCHAR と指定しても内部的には TEXT 型として扱われる。長さ制限は自動的に適用されない(制約として CHECK を使って制限可能)。

ストレージと長さの取り扱い(もう少し詳細)

VARCHARは「文字数」と「バイト数」の差を意識する必要があります。特にマルチバイト文字セット(utf8mb4など)を使う場合、1文字が複数バイトになるため、指定した n(多くの場合「文字数」)が実効的に格納可能なバイト数を超えてしまうことがあります。MySQL のように内部上限が行全体のバイト数で決まるエンジンでは、結果として許容できる最大文字数が減少します。

また、可変長の情報を管理するために長さプレフィックス(多くは1〜2バイト)や内部ヘッダーが付加されます。PostgreSQL の場合は varlena ヘッダ(通常4バイト)があり、短いデータ向けに最適化が入る場合もあります。

VARCHAR と CHAR、TEXT との使い分け

  • CHAR:固定長。短い固定長(例:都道府県コード、状態フラグなど)に向く。固定長のため、読み書きが安定しやすいがスペースを浪費することがある。末尾スペースでパディングされる実装が多い。
  • VARCHAR:可変長。長さが可変で、最大長がわかっているフィールド(ユーザー名、メールアドレスなど)に向く。
  • TEXT / CLOB:長大なテキスト用。全文検索や長文コンテンツに向くが、DBごとにデフォルト値の制約やインデックスの取り扱いが異なる(インデックスにプレフィックス指定が必要な場合がある)。

インデックスとパフォーマンス上の注意

VARCHARカラムをインデックス化する場合、DBエンジンはインデックスキー長の制限を持っていることが多いです。特にマルチバイト文字セットを使う場合、指定した文字数がインデックス可能なバイト長を超える可能性があります。MySQLのInnoDBでは過去にデフォルトでインデックスキー長が767バイトだった時期があり(現在は設定やフォーマットにより緩和されている)、utf8mb4だと varchar(191) などが実用的なインデックス長の目安として使われることがありました。

また、非常に長いVARCHARを頻繁に検索/ソートする用途ではパフォーマンスに影響が出ます。文字列比較やソートが重いため、必要ならハッシュ列や長さ制限、全文検索エンジンの利用(Elasticsearch、PostgreSQLのfull-textなど)を検討します。

文字セットと照合順序(コレーション)の影響

VARCHARでの比較・ソートはコレーションに依存します。大文字小文字を区別するか、アクセントを考慮するかなどがコレーションで決まり、これが検索結果やインデックスの利用に影響します。国際化対応ではUTF-8系(MySQLではutf8mb4)&適切なコレーションを選ぶことが重要です。

実務的な設計・運用上のポイント(チェックリスト)

  • 文字セットを明示する(MySQLなら utf8mb4 推奨)。マルチバイト化の影響を設計に反映する。
  • VARCHARの長さは実運用を観察して決める。過剰に大きくしすぎず、将来の余裕も考慮する。
  • インデックスを貼る場合、インデックスキー長上限を確認しておく(プレフィックスインデックスやhashなどの代替手段検討)。
  • 大量の可変長テキスト(記事本文やログなど)は TEXT 系にする、あるいは外部ストレージ(オブジェクトストア)を検討する。
  • ALTER TABLE でのカラム長変更はテーブルコピーを伴うことがあり、運用負荷が大きい。マイグレーションの計画を立てる。
  • SQLインジェクション対策としてバインドパラメータを使う。VARCHARのバウンダリチェックだけで安全とは限らない。

よくある誤解と注意点

  • 「VARCHARは文字数で指定すればOK」── 実際には内部でバイト数制限や行サイズ制限が関係するため、使用するDBの仕様を確認する必要がある。
  • 「VARCHARとTEXTは同じ」── 挙動やインデックス制約、デフォルト値の取り扱いがDBごとに異なるため、用途に応じて使い分けるべき。
  • 「長いVARCHARを作れば余裕」── 長さを無制限にしすぎると無駄なメモリ・I/Oを招くことがある。必要な最大長を想定して設計する。

短い例(SQLスニペット)

-- MySQL
CREATE TABLE users (
  id INT PRIMARY KEY,
  username VARCHAR(50) NOT NULL, -- utf8mb4 使用を想定して50文字
  bio TEXT
);

-- PostgreSQL
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  description TEXT
);

-- SQL Server
CREATE TABLE logs (
  id INT IDENTITY PRIMARY KEY,
  message VARCHAR(MAX) -- 大きなログを格納
);

まとめ

VARCHARは「可変長文字列」を効率よく扱うための基本的な型で、多くのDBで採用されています。ただし「長さの定義(文字数かバイト数か)」「文字セット」「インデックス制約」「ストレージの扱い」など、データベースごとに実装差があり、それらを理解しておかないと運用時に問題になります。設計段階では用途に応じてCHAR/VARCHAR/TEXTを使い分け、文字セット(utf8mb4など)やインデックスの制約を踏まえて最適化することが重要です。

参考文献