输入法字符集设置(mysql中文字符集设置)

lxf2023-07-05 20:50:01

最近在做一个关于mysql代理的项目,涉及到sql语句的解析。之前对mysql了解不多,但随着项目的进展不得不补上。今天突然看到mysql的charset设置,很多地方解释不清楚。对一些相关sql语句背后的工作机制略知一二,于是找了一些资料辅导,顺便做了一些笔记。

一.字符集和校对规则

字符集是一组符号和数字。校对规则是一组用于比较字符集中字符的规则。

文字是人类语言中最小的表意符号。如字母“A”、“B”等。;给定一系列字符,给每个字符一个数值,对应的字符用数值表示,这就是字符的编码。比如我们给字符‘A’赋值0,给字符‘B’赋值1,那么0就是字符‘A’的代码,1就是字符‘B’的代码;给定一系列字符和相应的代码,所有这些字符和代码对的集合就是一个字符集。

归类是指同一字符集中字符之间的比较规则;校对规则确定后,可以在一个字符集上定义什么是等价字符以及字符之间的大小关系;每个校对规则唯一对应一个字符集,但是一个字符集可以对应多个校对规则,其中一个是默认的校对规则。

Mysql可以做这些事情:

  • 使用多个字符集来存储字符串
  • 使用多个校对规则来比较字符串。
  • 使用不同的字符集或校对规则,在同一个服务器、同一个数据库甚至同一个表中混合字符串。
  • 允许您定义任何级别的字符集和校对规则。
  • 二、mysql字符集及校对

    Mysql服务器可以支持多种字符集,可以使用显示字符集。语句列出了可用的字符集:

    要列出校对规则,可以使用show collation声明:

    两个不同的字符集不能有相同的校对规则;此外,mysql中的校对规则名称遵循命名约定:它们以对应的字符集名称开头;以_ci(不区分大小写)、_cs(区分大小写)或_bin(按编码值比较)结尾。

    Mysql的字符集和校对规则有四个级别的默认设置:服务器级、数据库级、表级和连接级。

    1.服务器字符集和校对

    Mysql服务器有服务器字符集和服务器校对规则,两者都不能设置为空。

    Mysql按如下方式确定服务器字符集和服务器校对规则:

  • 根据服务器启动时的有效选项设置。
  • 根据运行时的设定值
  • 启动mysqld时,服务器字符集和校对规则是根据使用的初始选项设置来确定的。您可以使用- default-character-set-set来设置字符集,并且可以在字符集后添加- default-collation用于校对规则。如果未指定字符集,它与-default-character-set = latin1相同。如果只指定了一个字符集(例如,latin1),但没有指定校对规则,则它与-default-charset = latin1-default-collation = latin1_swedish_ci相同,因为latin1 _ Swedish _ ci是latin1的默认校对规则。因此,以下三个命令具有相同的效果:

    shell> mysqldshell> mysqld --default-character-set=latin1shell> mysqld --default-character-set=latin1 --default-collation=latin1_swedish_ci

    如果希望在从源程序构建时更改默认的服务器字符集和校对规则,可以重新编译并使用:- with-charset和- with-collation作为configure的参数。例如:

    shell> ./configure --with-charset=latin1

    或者:

    shell> ./configure --with-charset=latin1 --with-collation=latin1_german1_ci

    mysqld和configure都验证字符集/校对规则组合是否有效。如果无效,每个程序都会显示一条错误消息,然后终止。

    当前服务器字符集和校对规则可用作character_set_server和collation_server系统变量的值。这些变量的值可以在运行时更改,从而在运行时更改服务器字符集和校对规则。

    2.数据库字符集和校对

    每个数据库都有数据库字符集和数据库校对规则,不能空。

    create database和alter database语句有一个可选子句,用于指定数据库字符集和校对规则:

    create database db_name [[default] CHARACTER SET charset_name] [[default] COLLATE collation_name];alter database db_name [[default] CHARACTER SET charset_name] [[DEFAULT] COLLATE collation_name]; create database db_name default CHARACTER SET latin1 COLLATE latin1_swedish_ci;

    Mysql选择数据库字符集和数据库校对规则如下:

  • 如果指定了字符集X和校对规则Y,则采用字符集X和校对规则Y。
  • 如果指定了字符集X而没有校对Y,则采用字符集X的默认校对规则。
  • 否则,采用服务器字符集和服务器校对规则。
  • mysql创建数据库的语法...默认字符集...类似于标准sql的create table...字符集...因此,您可以在同一台mysql服务器上创建具有不同字符集和校对规则的数据库。

    如果create table语句中未指定表字符集和校对规则,则数据库字符集和校对规则将用作默认值。

    默认数据库的字符集和校对规则可以用作character_set_database和collation_database系统变量。每当默认数据库发生变化时,服务器都会设置这两个变量的值。如果没有默认数据库,这两个变量的值与相应的服务器级变量(character_set_server和collation_server)的值相同。

    3.表格字符集和校对

    每个表格都有表格字符集和校对规则,不能空。

    为了指定表字符集和校对规则,create table和alter table语句有一个可选子句:

    create table tbl_name ( column_list ) [default CHARACTER SET charset_name [COLLATE collation_name ]];alter table tbl_name [default CHARACTER SET charset_name] [COLLATE collation_name ] create table t1 ( ... ) default CHARACTER SET latin1 COLLATE latin1_danish_ci;

    Mysql选择表字符集和校对规则如下:

  • 如果指定了字符集X和排序Y,则使用字符集X和排序Y。
  • 如果指定了字符集X而没有校对Y,则采用字符集X的默认校对规则。
  • 否则,采用服务器字符集和服务器校对规则。
  • 如果在列定义中没有指定列字符集和校对规则,则默认使用表字符集和校对规则。表格字符集和校对规则是mysql的扩展;标准SQL中没有。

    4.列字符集和校对

    每个字符列(即CHAR、VARCHAR或TEXT类型的列)都有一个列字符集和一个列校对规则,不能是空。列定义语法有一个可选子句,用于指定列字符集和校对规则:

    col_name {CHAR | VARCHAR | TEXT} ( col_length ) [CHARACTER SET charset_name [COLLATE collation_name ]] create table table1(column1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_german1_ci);

    Mysql选择列字符集和校对规则如下:

  • 如果指定了字符集X和排序Y,则使用字符集X和排序Y。
  • 如果指定了字符集X而没有校对Y,则采用字符集X的默认校对规则。
  • 否则,采用表格字符集和校对规则。
  • 字符集和COLLATE子句是标准的SQL。

    5.连接字符集和校对

    如前所述,一些字符集和校对规则系统变量与客户端和服务器之间的交互有关:

  • 服务器字符集和校对规则可以用作character_set_server和collation_server变量的值。
  • l默认数据库的字符集和校对规则可以作为character_set_database和collation_database变量的值。
  • 客户端与服务器的连接还涉及字符集和校对规则变量。每个客户端都有一个与连接相关的字符集和校对规则变量。

    考虑一下“连接”是什么:它是当你连接到服务器时你所做的事情。客户端通过连接向服务器发送SQL语句,如查询。服务器通过连接向客户机发送响应,如结果集。对于客户端连接,这将导致一些关于连接的字符集和校对规则的问题,这些问题可以通过系统变量来解决:

  • 当查询离开客户端时,在查询中使用什么字符集?
  • 服务器使用character_set_client变量作为客户端发送的查询中使用的字符集。

  • l服务器收到查询后应该转换成什么字符集?
  • 在转换过程中,服务器使用character_set_connection和collation_connection系统变量。它将客户端发送的查询从character_set_client指示的字符集转换为character_set_connection指示的字符集(除非字符串文字有类似_latin1或_utf8的介词)。Collation_connection对于比较文字字符串很重要。对于列值的字符串比较,这并不重要,因为列具有更高的排序规则优先级。

    在内部操作之前,将请求的数据从character_set_connection转换为内部操作字符集,确定方法如下:

    a .使用每个数据字段的字符集设置值;

    B.如果以上值不存在,则使用对应数据表的默认字符集值(mysql扩展,非sql标准);

    c、如果上述值不存在,则使用对应数据库的默认字符集值;

    D.如果上述值不存在,请使用character_set_server设置该值。

  • 在向客户机发送结果集或返回错误消息之前,服务器应该转换成哪种字符集?
  • character_set_results变量表示服务器用来向客户机返回查询结果的字符集。包括诸如列值的结果数据和诸如列名的结果元数据。

    您可以调整这些变量的设置,也可以依赖默认值。

    有两个语句会影响连接字符集:

    set names ' charset_name ' SET CHARACTER SET charset_name;

    Set names显示客户端发送的sql语句中使用的字符集。因此,set names 'cp1251 '语句告诉服务器“来自该客户端的信息将来将使用字符集cp1251”。它还为服务器发送回客户端的结果指定字符集。(例如,如果使用SELECT语句,它会指示列值使用的字符集。)

    Set names' x '语句等价于这三个语句:

    set character_set_client = x ; set character_set_results = x ; set character_set_connection = x ;

    将x设置为character_set_connection还会设置默认校对规则,即collation_connection为x。

    set CHARACTER SET语句类似,但是连接字符集和校对规则是为默认数据库设置的。Set CHARACTER SET x语句等价于这三个语句:

    SET character_set_client = x ; SET character_set_results = x ; SET collation_connection = @@collation_database;

    当客户端连接时,它向服务器发送它想要使用的字符集的名称。服务器为该字符集设置character_set_client、character_set_results和character_set_connection变量。(实际上,服务器执行设置名称操作来使用这个字符集。)

    对于mysql客户端,如果您想使用不同于默认字符集的字符集,您不需要在每次启动时都执行set names语句。您可以在mysql语句行或选项文件中添加- default-character-set-set选项设置。例如,每次运行mysql时,以下选项文件设置会将三个字符集变量更改为utf8:

    [mysql]default-character-set=utf8 例如:假设 column1 定义为 CHAR(5) CHARACTER SET latin2 。如果没有设定 set names 或 set CHARACTER SET ,那么对于 select column1 from t ,当连接后,服务器使用客户端指定的字符集返回列 column1 的所有值。另一方面,如果你设定 set names 'latin1' 或 set CHARACTER SET latin1 ,那么发送结果之前,服务器转换 latin2 值到 latin1 。转换可能会丢失那些不属于两种字符集的字符。

    如果不希望服务器执行任何转换,请将character_set_results设置为NULL:

    mysql> SET character_set_results = NULL;

    6、字符串字符集和校对

    每个字符串都有字符集和校对规则,不能空。

    字符串可以有一个可选的字符集,引导介词和COLLATE子句:

    [_ charset_name ] ' string ' [COLLATE collation_name ] select ' string ';select _latin1 ' string ';select _latin1' string ' COLLATE latin1_danish_ci;

    对于简单语句select' string ',字符串使用由系统变量character_set_connection和collation_connection定义的字符集和校对规则。

    表达式_字符集_name官方称为介词。它告诉解析器,“稍后出现的字符串使用字符集x。”引用介词在标准的十六进制字母和数字十六进制符号(x' literal '和0x nnnn)中是合法的。

    select _latin1 x'AABBCC'; select _latin1 0xAABBCC;

    MySQL按如下方式确定字符集和校对规则:

  • 如果指定了字符集X和排序Y,则使用字符集X和排序Y。
  • 如果指定了字符集X而没有校对Y,则使用字符集X的默认校对规则。
  • 否则,将使用character_set_connection和collation_connection系统变量给出的字符集和校对规则。
  • 使用latin1字符集和latin1_german1_ci来校对规则字符串:
  • select _ latin1 ' M & uumlller ' COLLATE latin1 _ german1 _ ci

  • 使用latin1字符集及其默认校对规则(即latin1_swedish_ci)的字符串:
  • select _ latin1 ' M & uumlller ';

  • 使用连接默认字符集和校对规则的字符串:
  • 选择“M & uumlller ';

    字符集引用前置和COLLATE子句是根据标准SQL规范实现的。

    COLLATE可以用在很多SQL语句中:order by、as、group by、聚合函数、distinct、where、having等。COLLATE子句具有更高的优先级(高于||)。

    二元运算符是COLLATE子句的简写。BINARY' x '等效于' x' COLLATE y y,其中y是字符集' x '的二进制校对规则的名称。每个字符集都有一个二进制校对规则。例如,latin1字符集的二进制校对规则是latin1_bin,因此,如果A列是latin1字符集,则以下两条语句具有相同的效果:

    select * from t1 order by BINARY a;select * from t1 order by a COLLATE latin1_bin;

    7.校对规则的“可压缩性”

    在大多数查询中,mysql使用哪些校对规则进行比较是显而易见的。例如,在下列情况下,校对规则显然是“X列的列校对规则”:

    select x from T order by x;select x from T where x = x;select distinct x from T;

    但是,当涉及多个操作数时,可能会有歧义。例如:

    select x from T where x = 'Y';

    此查询应该使用X列或字符串文字“y”的校对规则吗?

    标准化的SQL使用“可压缩性”规则来解决这个问题。基本上这就意味着:既然X和Y都有校对规则,那么哪个校对规则优先?这可能很难解决,但以下规则适用于大多数情况:

  • 外部COLLATE子句的压缩率为0(根本无法压缩。)
  • 使用不同校对规则的两个字符串连接的压缩率为1。
  • 列校对规则的压缩率为2。
  • “系统常数”(如USER()或VERSION()函数返回的字符串)的可压缩性为3。
  • 文本规则的压缩率为4。
  • NULL或从NULL派生的表达式的压缩率为5。
  • 以上压缩值目前被mysql使用。

    这样,上述规则可以用模糊的方式求解:

  • 使用最低压缩值的校对规则。
  • 如果两边的压缩率相同,如果校对规则不同,就会出现错误。
  • 使用compressive()函数确定字符串表达式的可压缩性:

    mysql> SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci);-> 0mysql> SELECT COERCIBILITY(VERSION());-> 3mysql> SELECT COERCIBILITY('A');-> 4 adminjs.cn是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 Adminjs.cn还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 在Adminjs.cn中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!