2013-04-29 12 views
13

リクエストジェネレータでユニットテストを行っていて、LENGTH関数で問題が発生します。MySQL:utf8の文字列での奇妙なLENGTH()動作

私はお互いに次の2つの要求があります。

SHOW VARIABLES LIKE '%character%' 

は、次の結果を返します:

array(8) { 
    [0] => 
    array(2) { 
    'Variable_name' => 
    string(20) "character_set_client" 
    'Value' => 
    string(4) "utf8" 
    } 
    [1] => 
    array(2) { 
    'Variable_name' => 
    string(24) "character_set_connection" 
    'Value' => 
    string(4) "utf8" 
    } 
    [2] => 
    array(2) { 
    'Variable_name' => 
    string(22) "character_set_database" 
    'Value' => 
    string(6) "latin1" 
    } 
    [3] => 
    array(2) { 
    'Variable_name' => 
    string(24) "character_set_filesystem" 
    'Value' => 
    string(6) "binary" 
    } 
    [4] => 
    array(2) { 
    'Variable_name' => 
    string(21) "character_set_results" 
    'Value' => 
    string(4) "utf8" 
    } 
    [5] => 
    array(2) { 
    'Variable_name' => 
    string(20) "character_set_server" 
    'Value' => 
    string(4) "utf8" 
    } 
    [6] => 
    array(2) { 
    'Variable_name' => 
    string(20) "character_set_system" 
    'Value' => 
    string(4) "utf8" 
    } 
    [7] => 
    array(2) { 
    'Variable_name' => 
    string(18) "character_sets_dir" 
    'Value' => 
    string(26) "/usr/share/mysql/charsets/" 
    } 
} 

を私の2番目のリクエストは、次のとおりです。

SELECT LENGTH('重庆') as len 

それは6の代わりに、2を返します。 。

ここに何が問題なの?私のcharsetパラメータはよく見えます。

答えて

24

私はMySQL documentationに私の答えを見つけた:

LENGTH機能がバイトカウント:

mysql> SELECT LENGTH('重庆') ; 
+------------------+ 
| LENGTH('重庆') | 
+------------------+ 
|    6 | 
+------------------+ 
1 row in set (0.00 sec) 

CHAR_LENGTH機能が文字を数える:

mysql> SELECT CHAR_LENGTH('重庆') ; 
+-----------------------+ 
| CHAR_LENGTH('重庆') | 
+-----------------------+ 
|      2 | 
+-----------------------+ 
1 row in set (0.00 sec) 
+2

をより具体的には、 'LENGTH()は ')(CHAR_LENGTH'一方*バイト*における引数の長さを返し '*文字でその引数の長さを返します。 – eggyal

0

彼らの両方が完全に動作します違う:

LENGTH()は、文字列の長さを常にバイト単位で返します。 CHAR_LENGTH()は文字列の長さを文字で返します。

ほとんどの文字が2バイトでエンコードされているUnicodeを使用してしまえば、それは常に異なってくるでしょう。あるいは、私たちがUTF-8について話しているときでさえ、バイトの数は常に変化します。

例えば:

SELECT LENGTH('重庆'), CHAR_LENGTH('重庆'); 
--> 6, 2 
+0

あなたのコメントは間違っています。ユニコードはエンコーディングではないので、2バイトでエンコードしません。あなたはUTF-16について話しているのかもしれません。 Unicodeはコードポイントに関する仕様です。 – Johnny

関連する問題