DB: CHAR と VARCHAR

mysql> explain SELECT user_id, user_loginID, user_pic 
FROM users 
WHERE user_loginID='user1234' AND user_password_encrypted='aaa1234' 
AND user_status=1;
+----+-------------+-------+-------+-------------------------------------------------------------+---------------------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys                                               | key                 | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------------------------------------------------+---------------------+---------+-------+------+-------+
|  1 | SIMPLE      | users | const | user_loginID_UNIQUE,loginID_pw_index,loginID_emailcrc_index | user_loginID_UNIQUE | 50      | const |    1 | NULL  |
+----+-------------+-------+-------+-------------------------------------------------------------+---------------------+---------+-------+------+-------+
1 row in set (0.00 sec)
上記のクエリを例にとして、user_loginIDの保存方はVARCHAR(16)で、DBの文字設定規格はUTF-8(Unicode Transformation Format-8bit)となり、一般的には英語の文字元は 8bits(1byte)、中国語や日本語の字元は24bits(3byte)でコーディングされます。でも、このクエリのkey_len( user_loginID_UNIQUE の長さ)を見ると、ええ!?key_lenは50になります!預想の3*16 = 48 bytesではなく、2bytes増えました! 原因は、VARCHAR は動的な方法(dynamic)で文字元を保存します。だから、VARCHARは文字元以外にも他の参数が含めることになります。(例えば、文字元の長さや指向策定などの情報、一般的には2bytesくらいかかります)そして、これもCHARとVARCHAR VARCHARとの間で一番見やすい差格です。

事例

CHAR(10)  VARCHAR(10)この両方の中でもhelloという単語を保存されています。CHARの場合は10 Bytesにかかって、VARCHARは5Bytesだけでかかるそうです。
何なら、CHARはCHAR(10)に定義すると、その10Bytesのまま使いています。残りの 部分は空白にします。実際CHAR(10)に保存したデータはこいうhello_____形となります(5個の空白鍵が付加されています)。

VARCHAR? CHAR?

上記の事例から見ると、VARCHARのほうが壓倒的に有利だと思いますが。実際にプログラムする時、関数のアクセス効率も一つの考慮するべき要素となります。
例えば、user_loginID CHAR(10)定義する場合は、每回DBからのデータ檢察が10 Bytesに固定します。檢察內容による無駄な判断は必要がないです。だから、CHAR(10)の檢察は早いです。
それに比べると、VARCHAR保存方は動的に、すべでの字元はpointerとか、linking-listみたいな方法で保存します。その結果、システムがCPUの計算時間を消費します。

まとめ

  • CHAR 大きさが固定する、資源を無駄にする、計算に必要な時間が短い
  • VARCHAR 長さが固定されていない、その代わりにより多くのCPU時間を費やす必要がある

0 留言:

發佈留言