栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

MySQL非法混合排序规则

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MySQL非法混合排序规则

了解以下定义会有所帮助:

  • 字符编码 信息的每个符号是如何以二进制表示(并因此存储在计算机)。例如,符号

    é
    (U + 00E9,拉丁小字母E急性)被编码为
    0xc3a9
    在UTF-8 (它的MySQL呼叫
    utf8
    )和
    0xe9
    在窗口1252(其MySQL调用
    latin1
    )。

  • 字符集 是可使用给定字符编码表示符号的字母表。令人困惑的是,该术语还用于表示与字符编码相同的含义。

  • 核对 是在一个字符集的排序,以使字符串进行比较。例如:MySQL的

    latin1_swedish_ci
    排序规则将字符的大多数重音变体视为与基本字符等效,而它的
    latin1_general_ci
    归类将在下一个基本字符之前对它们进行排序,但不等效(还有其他更重要的区别:例如字符的顺序)喜欢
    å
    ä
    ö
    ß
    )。

MySQL将决定应将哪种排序规则应用于给定的表达式,如在“
排序规则的表达式”中所述:特别是,列的排序规则优先于字符串文字的排序规则。

WHERe
您的查询的WHERe子句比较以下字符串:

  1. 中的一个值

    fos_user.username
    ,以列的字符集(Windows-1252)编码,并表示对其排序规则的偏爱
    latin1_swedish_ci
    (强制性值为2);与

  2. 字符串文字

    'Nrv⧧Kasi'
    ,编码为连接的字符集(UTF-8,由Doctrine配置),并表示对连接的排序规则的偏爱
    utf8_general_ci
    (强制性值为4)。

由于这些字符串中的第一个比第二个具有较低的矫顽力值,因此MySQL尝试使用该字符串的排序规则执行比较

latin1_swedish_ci
。为此,MySQL尝试将第二个字符串转换为
latin1
-但由于该
字符集中不存在该字符,因此比较失败。


警告

应该暂停片刻,考虑一下该列当前的编码方式:您正在尝试过滤记录,

fos_user.username
该记录等于一个字符串,该字符串 包含 该列中
存在的字符

如果您认为该列 确实
包含此类字符,那么您可能在连接字符编码设置为某种字符(例如

latin1
)的情况下写了该列,这导致MySQL将接收到的字节序列解释为所有Windows-1252字符中的字符组。

如果是这种情况,请在继续操作之前修正数据!

  1. 将这些列转换为数据插入时使用的字符编码(如果不同于现有编码):

    ALTER TABLE fos_users MODIFY username VARCHAr(123) CHARACTER SET foo;
  2. 通过将与此类列关联的编码信息转换为

    binary
    字符集来删除它们:

    ALTER TABLE fos_users MODIFY username VARCHAr(123) CHARACTER SET binary;
  3. 通过将这些列转换为相关的字符集,与这些列关联的是实际传输数据的编码。

    ALTER TABLE fos_users MODIFY username VARCHAr(123) CHARACTER SET bar;

请注意,如果从多字节编码转换,则可能需要增加列的大小(甚至更改其类型),以适应转换后的字符串的最大可能长度。


一旦确定列已正确编码,就可以通过以下任一方法使用Unipre排序规则强制进行比较:

  • 将值显式转换

    fos_user.username
    为Unipre字符集:

    WHERe ConVERT(fos_user.username USING utf8) = ?
  • 强制字符串文字具有比列低的矫顽力值(将导致列的值隐式转换为UTF-8):

    WHERe fos_user.username = ? COLLATE utf8_general_ci

如您所说,也可以将列永久转换为Unipre编码并适当设置其排序规则。

我可以

utf8_general_ci
为所有表手动将排序规则更改为,而没有任何复杂性/注意事项吗?

原则上的考虑是,Unipre编码比单字节字符集占用更多的空间,因此:

  • 可能需要更多的存储空间;

  • 比较可能会慢一些;和

  • 索引前缀长度可能需要调整(请注意,最大值以字节为单位,因此表示的字符数可能比以前少)。

另外,请注意,如

ALTER TABLE
语法所示:

要更改默认的表字符集和所有字符列(

CHAR
VARCHAR
TEXT
)到一个新的字符集,可使用如下语句:

ALTER TABLE **_tbl_name_** 转换为字符集 ** _charset_name_** ;

对于数据类型为

VARCHAR
TEXT
类型之一的列,
ConVERTTO CHARACTERSET
将根据需要更改数据类型,以确保新列足够长以存储与原始列一样多的字符。例如,一
TEXT
列有两个长度的字节,它们存储该列中值的字节长度,最大为65,535。对于一
latin1

TEXT
列,每个字符都需要一个字节,因此该列最多可以存储65,535个字符。如果将列转换为
utf8
,则每个字符最多可能需要三个字节,最大可能的长度为3×65,535
=
196,605字节。该长度将不适合
TEXT
列的长度字节,因此MySQL会将数据类型转换为
MEDIUMTEXT
,这是长度字节可以记录196,605的最小字符串类型。同样,
VARCHAR
列可能会转换为
MEDIUMTEXT

为避免数据类型更改为刚刚描述的类型,请勿使用

ConVERT TO CHARACTER SET
。而是使用
MODIFY
更改单个列。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/421196.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号