MYSQL における char と varchar の違い

MYSQL における char と varchar の違い

CHAR 型と VARCHAR 型は似ていますが、主に格納場所、末尾のスペース、取得方法が異なります。

CHAR と VARCHAR の類似点は次のとおりです。CHAR と VARCHAR はどちらも文字の長さを指定します。文字の長さであることに注意してください。たとえば、char(30) と varchar(30) はどちらも 30 文字を格納できます。注意すべき点は、utf8mb4 エンコーディングでは、各文字が 4 つのノードを占有することです。 utf8 では、各文字は 3 バイトを占めます。格納する文字が CHAR/VARCHAR で指定された最大長を超える場合。 SQL モードが有効になっていない場合、保存される文字列は切り捨てられ、最初の 30 文字のみが保存されます。

CHAR列の値は固定長の文字列です。長さは 0 から 255 文字までの値で指定できます (例: utf8mb4: 0-255*4 バイト)。たとえば、文字を格納するために CHAR を使用する場合、例として CHAR(30) が使用されます。長さが 30 文字未満の場合は、右側にスペースが埋め込まれます。 CHAR 値が取得されると、sqlmode:PAD_CHAR_TO_FULL-LENGTH SQL モードが有効になっていない限り、末尾のスペースは削除されます。

VARCHAR 列の値は可変長文字列です。長さは 0 ~ 65535 バイトの範囲の値として指定できます。 VARCHAR の有効な最大長は、最大行サイズ (65535 バイト、すべての列で共有) と使用される文字セットによって異なります。

CHAR とは異なり、VARCHAR はデータを格納するときに追加の 1 ~ 2 バイトを格納します (たとえば、varchar(4) では、これらの 1 ~ 2 バイトは 4 文字の長さにカウントされないため、切り捨てを心配する必要はありません)。これらの 1 ~ 2 バイトは、データ文字の長さを記録するために使用されます。データ文字長が 255 以下の場合は、1 バイトを使用してデータ長を記録します。大きい場合は 2 バイトが使用されます。 CHAR はデータ自体のみを保存します。下の図の通りです。

(誤解: varchar (X) のバイト長が計算されるため、クエリの実行時に varchar の方が char よりも遅くなります)

latin1 エンコーディングでは、Latin1 は中国語の文字を保存できません。英語の文字は1バイトです。

価値文字(4)必要なストレージ可変長文字(4)必要なストレージ
'' ' ' 4バイト'' 1バイト
'アブ' 'アブ' 4バイト'アブ' 3バイト
'abcd' 'abcd' 4バイト'abcd' 5バイト
'abcdefgh' 'abcd' 4バイト'abcd' 5バイト

VARCHAR 値は保存時にスペースが埋め込まれないことに注意してください。標準 SQL に準拠して、値を保存および取得するときに末尾のスペースが保持されます。 CHAR はその逆です。CHAR は保存時にスペースが埋め込まれ、末尾のスペースが自動的に埋め込まれるか、データ自体に含まれているかに関係なく、取得時に末尾のスペースが削除されます。例えば:

mysql> テーブル vc (v VARCHAR(4), c CHAR(4)) を作成します。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)
 
mysql> vc VALUES ('ab ', 'ab ') に INSERT INTO します。
クエリは正常、1 行が影響を受けました (0.00 秒)
 
mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab) | (ab) |
+---------------------+---------------------+
セット内の 1 行 (0.06 秒)<br><br><br>

3つの実験を行ってください。

mysql> show テーブル vc を作成します。
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| テーブル | テーブルの作成 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| vc | テーブル `vc` を作成する (
 `v` varchar(4) デフォルト NULL,
 `c` char(4) デフォルト NULL,
 ユニークキー `v_UNIQUE` (`v`)
) エンジン=InnoDB デフォルト文字セット=utf8mb4 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
セット内の 1 行 (0.00 秒)

1. フィールド = 'ab' のクエリ ステートメント。

mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vc where v=' ab';
空のセット (0.00 秒)
 
mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vc where c=' ab';
空のセット (0.00 秒)

2. フィールド = 'ab ' のクエリ ステートメント。

mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vc where v='ab ';
+--------------------+--------------------+
| 連結('(',v, ')') | 連結('(',c, ')') |
+--------------------+--------------------+
| (ab ) | (ab) |
+--------------------+--------------------+
セット内の 1 行 (0.00 秒)
 
mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vc where c='ab ';
+--------------------+--------------------+
| 連結('(',v, ')') | 連結('(',c, ')') |
+--------------------+--------------------+
| (ab) | (ab) |
+--------------------+--------------------+
セット内の行は 1 行です (0.00 秒)<br><br><br>varchar、text、char のいずれの文字列比較でも、末尾のスペースは無視されます。ただし、like 句の場合は、次に示すように末尾のスペースは削除されません<br><br>
mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vipshop_dba.vc where c like 'ab'; (末尾のスペースなし)
+--------------------+--------------------+
| 連結('(',v, ')') | 連結('(',c, ')') |
+--------------------+--------------------+
| (ab) | (ab) |
| ( アブ ) | ( アブ ) |
+--------------------+--------------------+
セット内の 2 行 (0.00 秒)
 
mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vipshop_dba.vc where c like 'ab '; (末尾にスペースあり)
空のセット (0.00 秒)
 
 
 
CHAR は保存時にスペースが埋め込まれ、末尾のスペースが自動的に埋め込まれるか、データ自体の一部であるかに関係なく、取得時に末尾のスペースが削除されます。末尾のスペースを削除するこのアクションは、比較の前に実行されます。mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vipshop_dba.vc where v like 'ab '; (末尾にスペースがあります)
+--------------------+--------------------+
| 連結('(',v, ')') | 連結('(',c, ')') |
+--------------------+--------------------+
| (ab ) | (ab) |
+--------------------+--------------------+
セット内の1行(0.01秒)
 
mysql> SELECT concat('(',v, ')'),concat('(',c, ')') FROM vipshop_dba.vc where v like 'ab'; (末尾のスペースなし)
空のセット (0.00 秒)

3. varcharに一意のインデックスを設定し、「ab」と「ab」が同時に存在できるかどうかを確認します。

mysql> vc (v,c)values('ab ', 'ab ') に挿入
 -> ;
エラー 1062 (23000): キー 'v_UNIQUE' のエントリ 'ab ' が重複しています
mysql> vc (v,c)values('ab', 'ab') に挿入します
 -> ;
クエリは正常、1 行が影響を受け、1 つの警告 (0.00 秒)<br>これは、varchar の末尾のスペースは保持できますが、インデックスに追加の制限が課せられている可能性があることを示しています。 varchar が一意のインデックスであり、挿入された値が末尾のスペースの数のみ異なる場合、重複キーが報告されます。

バイト制限について言えば、これもお知らせしたいと思います。インデックスの長さにも制限があります。

InnoDB エンジンの各インデックス列の長さは 767 バイトに制限されており、すべてのインデックス列の合計長は 3072 バイトを超えることはできません。バイトであることに注意してください。varchar(256) のバイト計算は、エンコーディングによって異なります。たとえば、utf8mb4 では 1 文字が 4 バイトを占め、256 文字 = 1024 バイトになります。インデックスカバレッジの効果は得られません。これはプレフィックスインデックスのみを作成するのと同じです(非常に重要、プレフィックスインデックスはセカンダリクエリの(主キー)テーブルに返される必要があります)

innodb エンジンは、innodb_large_prefix=on (グローバル パラメータ、動的に有効) を構成することにより、単一のインデックス列の長さ制限を 3072 バイトまで増やすことができます。

  • MySQL 5.7 では、デフォルトの innodb_large_prefix=1 により 767 バイトの長さ制限が削除されますが、単一列インデックスの最大長は 3072 バイトを超えることはできません。
  • MySQL 5.6 では、デフォルトの innodb_large_prefix=0 により、単一列インデックスの長さが 767 バイト以下に制限されます。 innodb_large_prefix=ON、innodb_file_format=barracuda、innodb_file_per_table=ONに設定し、Innodbテーブルのストレージ形式がDYNAMICまたはCOMPRESSEDの場合、プレフィックスインデックスには最大3072バイトを含めることができます。

上記はMYSQLにおけるcharとvarcharの違いの詳細な内容です。MYSQLのcharとvarcharの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • 面接官がmysqlのcharとvarcharの違いを尋ねたとき
  • MySQL の char、varchar、text フィールド タイプの違い
  • MySQL における VARCHAR と CHAR 形式のデータの違い
  • MySQL データベースにおける char と varchar の違いの分析と使用上の提案
  • MySQL の char と varchar の違いの分析
  • MySQL における varchar 型と char 型の違い

<<:  Vue ベースの円形スクロールリスト機能を実装する

>>:  Linux gzipコマンドの使用

推薦する

Linux (Centos7) での redis5 クラスターの構築と使用方法の詳細な説明

目次1. 簡単な説明2. クラスターを作成する手順2.1. ディレクトリを作成する2.2. ソースコ...

Docker イメージのインポートとエクスポートのコード例

Dockerイメージのインポートとエクスポートこの記事では、移行、バックアップ、アップグレードなどの...

localStorageの有効期限を設定するいくつかの方法

目次問題の説明1. 基本的な解決策2. 中間的な解決策3. 高度なソリューション4. ハードコアソリ...

nginx のロケーションと書き換えの使用法の詳細な説明

1. 位置情報の利用状況の概要ロケーションは、さまざまな処理方法に対してさまざまな種類のリクエストを...

CSS3 で作成したホバーズーム効果

結果:実装コード: html <link href='https://fonts.go...

HTMLのタグと要素の違いの詳細な説明

ウェブページに慣れていない友人の多くは私と同じように、HTML で要素、タグ、属性がどのように定義さ...

MySQL のマスター スレーブ レプリケーション オプションをオンラインで変更する方法

序文: MySQL で最も一般的に使用されるアーキテクチャは、マスター スレーブ レプリケーションで...

ウェブページの読み込み速度を上げる簡単なヒント

Web ページの読み込み速度は、Web サイトの品質を評価するための重要な指標です。その理由は、ほと...

ES6スプレッド演算子の使用例

目次スプレッド演算子とレスト演算子とは何ですか?配列スプレッド演算子残り演算子(コレクション関数)ス...

Navicat がリモートで SQL Server に接続し、MySQL に変換する詳細な手順

序文最近、プロジェクトで SQL Server を使用するプログラムに遭遇しました。このデータベース...

ins タグと del タグの属性と使用法

insとdel は、HTML 4.0 で導入され、文書の作成時に作成者が共同作業できるようにし、また...

MySQLチュートリアルではストアドプロシージャを徹底的に理解します

目次1. ストアドプロシージャに関連する概念2. ストアドプロシージャの使用1) ストアドプロシージ...

MySQL 5.5 で範囲パーティションを追加および削除する例

導入RANGE パーティション分割は、指定された連続した間隔範囲に基づいています。RANGE の初期...

MySQL マルチテーブルクエリの詳細な説明

よく食べて十分に休息を取るというのは簡単なことのように思えますが、実際に実行するのはそれほど簡単では...

Javascript を使用して、スライドバー効果のあるスライドナビゲーション プラグインを開発します。

目次1. はじめに2. 使用方法3. 開発プロセス1. モデル例2. イベントとアニメーション4. ...