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ルートの初期値を設定する方法の簡単な分析

Ubuntu ではデフォルトで root ログインが許可されていないため、初期の root アカウン...

HTML での一般的なリダイレクト接続の例コード

コードをコピーコードは次のとおりです。 window.location.href="zcb...

MySQL ifnull のネスト使用手順

MySQL ifnull のネストされた使用ifnull をネストする方法があるかどうかオンラインで...

Windows 10 での MySQL 8.0.12 解凍バージョンのインストール グラフィック チュートリアル

この記事は、MySQL 8.0.12解凍版のインストールグラフィックチュートリアルを記録しています。...

Google ブラウザのラベルと入力間のスペースに関する小さな問題

最初にコード、次にテキストコードをコピーコードは次のとおりです。 <!DOCTYPE html...

CentOS7 で MySQL データベースにリモート接続できない理由と解決策

序文最近、仕事で問題が発生しました。 Centos7 システムでは MySQL にリモート接続できな...

html、xhtml、xmlの違い

開発動向: html (ハイパーテキスト マークアップ言語) - xhtml (拡張ハイパーテキスト...

nginx をベースにした Web クラスター プロジェクトをすばやく構築する方法を説明します。

目次1. プロジェクト環境2. プロジェクトの説明3. プロジェクトの手順1. インストール2. 構...

フロントエンドに必要なNginx設定の詳細な説明

Nginx (エンジン x) は、軽量で高性能な HTTP およびリバース プロキシ サーバーであり...

Javascriptのクロージャとアプリケーションの詳細な説明

目次序文1. クロージャとは何ですか? 1.1 クロージャは条件コードを満たす1.2 クロージャ生成...

HTMLボタンを中央に配置する方法

HTML ボタン自体を中央に配置するにはどうすればよいでしょうか? このアイデアは簡単に見つかります...

JavaScript におけるセミコロンの詳細

序文JavaScript ではセミコロンはオプションであり、使用するかどうかは主にコーディング スタ...

Dockerを使用してコンテナリソースを制限する方法

覗き見の問題サーバーでは、IIS サービスが複数のサイトを展開していると仮定すると、サイトの 1 つ...

Vue はコンポーネント間の通信をどのように実装しますか?

目次1. 父と息子のコミュニケーション1.1 親コンポーネント --> 子コンポーネント1.2...

Vueは3段階のナビゲーション表示と非表示を実装します

この記事では、3階層ナビゲーションの表示と非表示を実現するためのVueの具体的なコードを例として紹介...