在服务器和客户端设置相同的字符集对程序运行的影响如下:
bool Protocol::net_store_data(const uchar *from, size_t length,
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
{
uint dummy_errors;
/* Calculate maxumum possible result length */
uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
if (conv_length > 250)
{
/*
For strings with conv_length greater than 250 bytes
we don't know how many bytes we will need to store length: one or two,
because we don't know result length until conversion is done.
For example, when converting from utf8 (mbmaxlen=3) to latin1,
conv_length=300 means that the result length can vary between 100 to 300.
length=100 needs one byte, length=300 needs to bytes.
Thus conversion directly to "packet" is not worthy.
Let's use "convert" as a temporary buffer.
*/
return (convert->copy((const char*) from, length, from_cs,
to_cs, &dummy_errors) ||
net_store_data((const uchar*) convert->ptr(), convert->length()));
}
Copy函数如下:
bool String::copy(const char *str, uint32 arg_length,
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
{
uint32 offset;
DBUG_ASSERT(!str || str != Ptr);
if (!needs_conversion(arg_length, from_cs, to_cs, &offset))//判断是否需要转换,哪种情况不需要转换呢,稍后显示
{
*errors= 0;//复制数据到目标缓冲区
return copy(str, arg_length, to_cs);
}
if ((from_cs == &my_charset_bin) && offset)//如果不能直接复制,下面就是要对字符进行转换后重新复制,这中间当然会浪费时间,为什么不能够复制呢,因为不同的字符集之间同一字符占用的字节数都是不一样的,如果强制复制当然会造成乱码的了。
{
*errors= 0;
return copy_aligned(str, arg_length, offset, to_cs);
}
uint32 new_length= to_cs->mbmaxlen*arg_length;
if (alloc(new_length))
return TRUE;
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
str, arg_length, from_cs, errors);
str_charset=to_cs;
return FALSE;
}
下面的用于判断是否需要转换的函数
bool String::needs_conversion(uint32 arg_length,
CHARSET_INFO *from_cs,
CHARSET_INFO *to_cs,
uint32 *offset)
{
*offset= 0;
if (!to_cs ||
(to_cs == &my_charset_bin) ||
(to_cs == from_cs) ||
my_charset_same(from_cs, to_cs) ||
((from_cs == &my_charset_bin) &&
(!(*offset=(arg_length % to_cs->mbminlen)))))
return FALSE;
return TRUE;
}
恩 下班了 MySQL自己封装的字符串应该要好好看看,在文件sql_string.h和sql_string.cc中