5.10. MySQL本地化和国际应用
- 5.10.1. 数据和排序用字符集
- 5.10.2. 设置错误消息语言
- 5.10.3. 添加新的字符集
- 5.10.4. 字符定义数组
- 5.10.5. 字符串比较支持
- 5.10.6. 多字节字符支持
- 5.10.7. 字符集问题
- 5.10.8. MySQL服务器时区支持
5.10.1. 数据和排序用字符集
- 5.10.1.1. 使用德国字符集
默认情况下,MySQL使用cp1252(Latin1)字符集根据Swedish/Finnish规则进行排序。这些默认值适合美国和西欧大部分国家。
所有MySQL二进制分发版用--with-extra-charsets=complex编译而成。可以在所有标准程序中添加代码,使它们可以处理latin1和所有多字节二进制字符集。其它字符集根据需要从字符集定义文件载入。
字符集确定在名称中使用什么字符。它还确定如何用SELECT语句的ORDER BY和GROUP BY子句对字符串进行排序。
还可以在启动服务器时用--default-character-set选项更改字符集。字符集可以用--with-charset=charset和--with-extra-charsets=list-of-charsets | complex | all | none选项来configure,字符集配置文件列于SHAREDIR/charsets/Index。参见2.8.2节,“典型配置选项”。
还可以在你启动服务器时用--default-collation选项更改字符集校对规则。校对规则必须是默认字符集的合法校对规则。(使用SHOW COLLATION语句来确定每个字符集使用哪个校对规则)。 参见2.8.2节,“典型配置选项”。
如果在运行MySQL时更改字符集,还会更改排序顺序。结果是你必须对所有表运行myisamchk -r -q --set-character-set=charset,或正确地对索引进行排序。
当客户端连接MySQL服务器时,服务器告诉客户端服务器的默认字符集是什么。客户端切换到该字符集进行连接。
当转义SQL查询的字符串时,你应使用mysql_real_escape_string()。mysql_real_escape_string()等价于旧的mysql_escape_string()函数,不同的是它使用MYSQL连接句柄作为第一个参数,以便转义字符时可以使用相应的字符集。
如果客户端的编译路径不是服务器的安装目录,并且配置MySQL时没有包括MySQL二进制中的所有字符集,如果服务器运行时需要使用客户端设置的字符集之外的其它字符集,你必须告诉客户端从哪里找到更多的字符集。
可以指定--character-sets-dir选项来表示动态MySQL字符集所保存目录的路径。例如,可以将下面的行放入选项文件中:
[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets
你可以强制客户端使用专用字符集:
[client]
default-character-set=charset
但是一般情况不需要。
5.10.1.1. 使用德国字符集
在MySQL 5.1中,分别指定字符集和校对规则。这说明如果你想使用German排序顺序,你应选择latin1字符集和latin1_german1_ci或latin1_german2_ci校对规则。例如,要用latin1_german1_ci校对规则启动服务器,应使用--character-set-server=latin1和--collation-server=latin1_german1_ci选项。
关于这两种校对规则的不同之处,参见10.10.2节,“西欧字符集”。
5.10.2. 设置错误消息语言
默认情况下,mysqld用英语给出错误消息,但也可以用以下语言显示:Czech、Danish、Dutch、Estonian、French、German、Greek、Hungarian、Italian、Japanese、Korean、Norwegian、Norwegian-ny、Polish、Portuguese、Romanian、Russian、Slovak、Spanish或 Swedish。要想在启动mysqld后用具体语言显示错误消息,使用--language或-L选项。选项值可以为语言名称或错误消息文件的全路径。例如:
shell> mysqld --language=swedish
或:
shell> mysqld --language=/usr/local/share/swedish
语言名应为小写。
语言文件位于(默认情况下)MySQL基本目录的share/LANGUAGE目录下。
要想更改错误消息文件,应编辑errmsg.txt文件,然后执行下面的命令以生成errmsg.sys文件:
shell> comp_err errmsg.txt errmsg.sys
如果你升级到新版本的MySQL,记住使用新的errmsg.txt文件来重新更改。
5.10.3. 添加新的字符集
本节讨论在MySQL中添加新字符集的程序。你必须有一个MySQL源码分发版。
要选择正确的程序,先确定字符集是简单字符集还是复杂字符集:
·如果字符集不需要使用特殊字符串校对规则程序进行排序,并且不需要多字节字符支持,则为简单字符集。
·如果需要上述某个特性,则为复杂字符集。
例如,latin1和danish为简单字符集,而big5和czech为复杂字符集。
在下面的程序中,字符集名用MYSET表示。
对于简单字符集,应:
1. 在sql/share/charsets/Index文件最后添加MYSET。并指定唯一的编号。
2. 创建文件sql/share/charsets/MYSET.conf。(你可以使用sql/share/charsets/latin1.conf的备份文件作为该文件的基础)。
该文件的语法很简单:
·注释从‘#’字符开始,一直到该行末尾。
·各字之间用任意数量的空格间隔开。
·定义字符集时,每个字必须为十六进制格式的数字。
·ctype数组占据前257个字。to_lower[]、to_upper[]和sort_order[]数组依次占据256个字。
参见5.10.4节,“字符定义数组”。
3. 将字符集名添加到configurE.in的CHARSETS_AVAILABLE和COMPILED_CHARSETS列。
4. 重新配置、编译并测试。
对于复杂字符集,应:
1. 在MySQL源码分发版中创建文件strings/ctype-MYSET.c。
2. 在sql/share/charsets/Index文件最后添加MYSET。并指定唯一的编号。
3. 看看已有的ctype-*.c文件(例如strings/ctype-big5.c),看看需要定义什么。请注意文件中的数组名必须为ctype_MYSET、to_lower_MYSET等等。对应简单字符集的数组。参见5.10.4节,“字符定义数组”。
4. 在文件顶部,添加注释:
5. /*
6. * This comment is parsed by configure to create ctype.c,
7. * so don't change it unless you know what you are doing.
8. *
9. * .configure. number_MYSET=MYNUMBER
10.* .configure. strxfrm_multiply_MYSET=N
11.* .configure. mbmaxlen_MYSET=N
12.*/
configure程序使用该注释自动将字符集包括进MySQL库中。
在下面章节中解释strxfrm_multiply和mbmaxlen行。只有需要字符串比较函数或多字节字符集函数时,才需要单独将它们包括进来。
13.然后你应创建下面的函数:
- my_strncoll_MYSET()
- my_strcoll_MYSET()
- my_strxfrm_MYSET()
- my_like_range_MYSET()
参见5.10.5节,“字符串比较支持”
14.将字符集名添加到configurE.in的CHARSETS_AVAILABLE和COMPILED_CHARSETS列。
15.重新配置、编译并测试。
sql/share/charsets/README文件中包括详细的说明。
如果你想要MySQL分发中的字符集,请向MySQL内部邮件系统发邮件。参见1.7.1.1节,“The MySQL邮件列表”。
5.10.4. 字符定义数组
to_lower[]和to_upper[]是简单数组,含有小写和大写字符,对应字符集的每个成员。例如:
to_lower['A'] should contain 'a'
to_upper['a'] should contain 'A'
sort_order[]是一个映射,表示如何排列字符的顺序,以便进行比较和排序。通常(但非对于所有字符集)与to_upper[]相同,说明排序对大小写敏感。MySQL排序字符基于sort_order[]元素的值。对于更加复杂的排序规则,参见5.10.5节,“字符串比较支持”的字符串校对规则讨论。
ctype[]是一个位数组,每个字符为一个元素。(请注意字符值索引to_lower[]、to_upper[]和sort_order[],但用字符值+ 1索引ctype[]。这是传统的转换方法,能够处理EOF)。
m_ctype.h中有下面的位掩码定义:
#define _U 01 /* Uppercase */
#define _L 02 /* Lowercase */
#define _N 04 /* Numeral (digit) */
#define _S 010 /* Spacing character */
#define _P 020 /* Punctuation */
#define _C 040 /* Control character */
#define _B 0100 /* Blank */
#define _X 0200 /* heXadecimal digit */
每个字符的ctype[]条目应为相应的描述字符的位掩码值的联合。例如,'A'是大写字符(_U)以及十六进制整数(_X),因此ctype['A'+1]应包含 值:
_U + _X = 01 + 0200 = 0201
5.10.5. 字符串比较支持
如果语言的排序规则比较复杂,不能用简单sort_order[]表来处理,需要使用字符串比较函数。最好的文档是已有字符集。以big5、czech、gbk、sjis和tis160字符集作为例子。
你必须在文件顶部的特殊注释处指定strxfrm_multiply_MYSET=N值。N应设置为字符串在my_strxfrm_MYSET过程中可能增长的最大比例(必须为正整数)。
5.10.6. 多字节字符支持
如果你想要添加包括多字节字符的新字符集支持,需要使用多字节字符函数。最好的文档是已有字符集。以euc_kr、gb2312,gbk、sjis和ujis字符集作为例子。这些字符集位于strings目录的ctype-charset.c文件中。
必须在文件顶部的特殊注释处指定mbmaxlen_MYSET=N值。N应设置为字符集内最长字符的字节数。
5.10.7. 字符集问题
如果你想要使用没有编译为二进制的字符集,可能会遇到下面的问题:·你的程序的字符集保存路径不正确。(默认为/usr/local/mysql/share/mysql/charsets)。可以在运行有问题的程序时通过--character-sets-dir选项来修复。
·字符集为多字节字符集,不能动态载入。在这种情况下,你必须重新编译程序,以支持字符集。
·字符集为动态字符集,但你没有对应的配置文件。在这种情况下,你应从新MySQL分发安装该字符集的配置文件。
·如果Index文件没有包含字符集名,程序将显示下面的错误消息:
·ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf'
·not found (Errcode:2)
在这种情况下,你应获得新Index文件或在当前文件中手动添加字符集。
对于MyISAM表,可以用myisamchk -dvv tbl_name检查表的字符集名和编号。
5.10.8. MySQL服务器时区支持
MySQL服务器有几个时区设置:
·系统时区。服务器启动时便试图确定主机的时区,用它来设置system_time_zone系统变量。
·服务器当前的时区。全局系统变量time_zone表示服务器当前使用的时区。初使值为'SYSTEM',说明服务器时区与系统时区相同。可以用--default-time-zone=timez选项显式指定初使值。如果你有SUPER权限,可以用下面的语句在运行时设置全局变量值:
·mysql> SET GLOBAL time_zone = timezone;
·每个连接的时区。每个客户端连接有自己的时区设置,用会话time_zone变量给出。其初使值与全局变量time_zone相同,但可以用下面的语句重设:
·mysql> SET time_zone = timezone;
可以用下面的方法查询当前的全局变量值和每个连接的时区:
mysql> SELECT @@global.time_zone, @@session.time_zone;
timezone值为字符串,表示UTC的偏移量,例如'+10:00'或'-6:00'。如果已经创建并装入mysql数据库中的时区相关表,你还可以使用命名的时区,例如'Europe/Helsinki'、'US/Eastern'或'MET'。值'SYSTEM'说明该时区应与系统时区相同。时区名对大小写不敏感。
MySQL安装程序在mysql数据库中创建时区表,但不装载。你必须手动装载。(如果你正从以前的版本升级到MySQL 4.1.3或更新版本,你应通过升级mysql数据库来创建表。参见2.10.2节,“升级授权表”中的说明)。
如果你的系统有自己的时区信息数据库(描述时区的一系列文件),应使用mysql_tzinfo_to_sql程序来填充时区表。示例系统如Linux、FreeBSD、Sun Solaris和Mac OS X。这些文件的可能位置为/usr/share/zoneinfo目录。如果你的系统没有时区信息数据库,可以使用本节后面描述的下载的软件包。
mysql_tzinfo_to_sql程序用来装载时区表。在命令行中,将时区信息目录路径名传递到mysql_tzinfo_to_sql并输出发送到mysql程序。例如:
shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
mysql_tzinfo_to_sql读取系统时区文件并生成SQL语句。mysql处理这些语句并装载时区表。
mysql_tzinfo_to_sql还可以用来装载单个时区文件,并生成闰秒信息。
要想装载对应时区tz_name的单个时区文件tz_file,应这样调用mysql_tzinfo_to_sql:
shell> mysql_tzinfo_to_sql tz_file tz_name | mysql -u root mysql
如果你的时区需要计算闰秒,按下面方法初使化闰秒信息,其中tz_file是时区文件名:
shell> mysql_tzinfo_to_sql --leap tz_file | mysql -u root mysql
如果你的系统没有时区信息数据库 (例如,Windows或HP-UX),你可以从http://dev.mysql.com/downloads/timezones.html下载预构建时区表软件包。该软件包包含MyISAM时区表所用的.frm、.MYD和.MYI文件。这些表应属于mysql数据库,因此应将这些文件放到MySQL服务器数据目录的mysql子目录。操作时应关闭服务器。
警告!如果你的系统有时区信息数据库,请不要使用下载的软件包。而应使用mysql_tzinfo_to_sql实用工具!否则,MySQL和系统上其它应用程序处理日期时间的方法会有所不同。
关于在复制时时区设置相关请查阅6.7节,“复制特性和已知问题”。