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コマンドの使用

推薦する

Dockerのデフォルトネットワークセグメントの正しい変更手順

背景同僚がセキュリティ プロジェクトに取り組んでおり、AWS サーバーに秘密兵器を展開する必要があり...

この記事では、CSSのようなJSモジュールをインポートする方法を説明します。

目次序文構築可能なスタイルシートとは何ですか? CSSモジュールスクリプトの使用インポートアサーショ...

MySQL クエリのパケットが大きすぎる問題と解決策

問題の説明:エラーメッセージ:原因: com.mysql.jdbc.PacketTooBigExce...

HTML 選択オプションの基本的な理解と使用

JavaScript での HTML (選択オプション) の詳細な説明1. 基本的な理解:コードをコ...

Docker-compose インストール yml ファイルの設定方法

目次1. オフラインインストール2. オンラインインストール3. アンインストール4. ymlファイ...

よくある CSS エラーと解決策

コードをコピーコードは次のとおりです。 IE6 と FF の違い: background:orang...

Dockerボリュームのファイルマッピング方法

背景ブロックチェーン ログ モジュールで作業しているときに、コンテナーが実行されている場合は、ログ ...

CSSページ下部固定を実現する8つの方法の詳細な説明

ページを書いているときに、ページの内容が小さくてフッターがページの真ん中に留まってしまうといった状況...

MySQL 最適化のケーススタディ

1. 背景Youzan の各 OLTP データベース インスタンスには、実行時間が特定のしきい値を超...

MySQL 外部キー制約の詳細な説明

公式ドキュメント: https://dev.mysql.com/doc/refman/5.7/en/...

Spring Cloud での Docker デプロイメントに jib を使用する詳細な手順

ジブの紹介Jib は Google が開発した、Java アプリケーションの Docker および ...

WeChatアプレットでグローバル変数を監視する方法

最近、仕事で問題に遭遇しました。グローバル変数 red_heart があります。これは多くの場所で使...

要素ツリーコントロールは、ドロップダウンメニューとアイコンを統合します(ツリー+ドロップダウン+入力)

目次要件:実装手順:この記事では主に以下について説明します: カスタムツリーコントロール<el...

WeChat アプレット wxs 日付と時刻処理の実装例

目次1. 日付までのタイムスタンプ2. UTCを北京時間に変換するWXS (WeiXin Scrip...

MySQL プロセス制御 IF()、IFNULL()、NULLIF()、ISNULL() 関数

MySQL では、IF()、IFNULL()、NULLIF()、および ISNULL() 関数を使用...