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

推薦する

MySQLにおけるMTRの概念

MTR は Mini-Transaction の略です。名前が示すように、これは「最小のトランザクシ...

htmlダウンロード機能の詳しい説明

新しいプロジェクトは基本的に終了しました。フロントエンドとバックエンドを分離して統合を完了したのは初...

Vue3.0 における Ref と Reactive の違いの詳細な分析

目次参照と反応参照反応的RefとReactiveの違いshallowRef と shallowRea...

CentOS 6 は Docker を使用して Redis マスター スレーブ データベース操作例を展開します

この記事では、Docker を使用して Centos6 に Redis マスター/スレーブ データベ...

Web2.0: 情報過多の原因と解決策

<br />情報の重複、情報過多、情報強迫、パーソナライズされたカスタマイズ、検索エンジ...

あなたのウェブサイトはIE8に適していますか?

オリンピック期間中にIE8ベータ2がリリースされ、英語版のリリースに合わせて中国語版も第一波でリリー...

ユーザーエクスペリエンスの要素またはWebデザインの要素

システムとユーザー環境の設計<br />Apple システムの成功は、そのシステム アー...

nginx+uwsgi で Django プロジェクトを開始するための詳細な手順

Django で Web プロジェクトを開発する場合、開発およびテストのプロセスでは Django ...

HTML+CSSを使用してTG-visionホームページを作成する方法

今回はHTML+CSSレイアウトを使用して、TG-vision Shuanghui Mediaのホー...

vue N​​progress のプログレスバー機能を実装する際の一般的な問題

NProgress は、ページがジャンプしたときにブラウザの上部に表示される進行状況バーです。公式ウ...

CocosCreatorでJSZip圧縮を使用する方法

CocosCreator バージョン: 2.4.2 jszipの実践的なプロジェクトアプリケーション...

VUE ユニアプリコア知識の簡単な紹介

目次仕様a. ページファイルはVueの単一ファイルコンポーネント仕様に準拠しています。 b. コンポ...

Reactにおける制御されたコンポーネントと制御されていないコンポーネントの簡単な分析

目次制御されていないコンポーネント制御コンポーネント知らせ結論は制御されていないコンポーネントフォー...

UbuntuはSSHサービスのリモートログイン操作を開始します

ssh-secure シェルは、安全なリモート ログインを提供します。組み込みシステムを開発し、Li...

GoogleとFacebookがDockerを使わない理由

この記事を書いた理由は、修正した分散 PyTorch プログラムを Facebook のクラスター上...