草庐IT

mysql - MySQL非法混合排序规则

coder 2023-06-10 原文

在查看我的Prod日志后,我有一些错误提到:

[2012-08-31 15:56:43] request.CRITICAL: Doctrine\DBAL\DBALException: 
An exception occurred while executing 'SELECT t0.username ....... FROM fos_user t0 WHERE t0.username = ?'
with params {"1":"Nrv\u29e7Kasi"}:

SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (latin1_swedish_ci,IMPLICIT)
and (utf8_general_ci,COERCIBLE) for operation '=' 

Alghout I在Cfg条令下有UTF-8默认值:
doctrine:
    dbal:
        charset:  UTF8

似乎我所有的MySQL表都在latin1_swedish_ci中,所以我的问题是:
对于我的所有表,我可以手动将排序规则更改为utf8_general_ci而不需要任何复杂/预防措施吗?

最佳答案

有助于理解以下定义:
字符编码详细说明了如何用二进制(因此存储在计算机中)表示每个符号。例如,符号é(u+00e9,带锐音符的拉丁文小写字母e)是encodedas0xc3a9inUTF-8(which mysql callsutf8)和0xe9inWindows-1252(which mysql callslatin1)。
字符集是可以用给定的字符编码表示的符号的字母表。令人困惑的是,这个术语也被用来表示与字符编码相同的含义。
排序规则是对字符集的排序,以便可以比较字符串。例如:mysql的latin1_swedish_ci排序规则将一个字符的大多数重音变体视为等同于基字符,而其latin1_general_ci排序规则将在下一个基字符之前排序,但不等同(还有其他更重要的区别:例如字符的顺序likeåäöß)。
MySQL将决定应将哪个排序规则应用于给定表达式,如Collation of Expressions中所述:特别是,列的排序规则优先于字符串文本的排序规则。
查询的WHERE子句比较以下字符串:
fos_user.username中的值,编码在列的字符集(windows-1252)中,并表示对其排序规则的首选项(强制值为2);with
字符串literallatin1_swedish_ci,编码在连接的字符集(utf-8,按条令配置)中,表示对连接的排序规则的偏好(强制值为4)。
由于第一个字符串的强制值低于第二个字符串,MySQL尝试使用该字符串的排序规则执行比较:'Nrv⧧Kasi'。为此,MySQL尝试将第二个字符串转换为utf8_general_ci—但由于该字符集中不存在latin1_swedish_ci字符,因此比较失败。
警告
应该暂停片刻,考虑列当前是如何编码的:您正试图筛选latin1等于包含该列中不能存在的字符的字符串的记录!
如果您认为该列确实包含这样的字符,那么您可能会在连接字符编码设置为某个(例如)时写入该列,这会导致MySQL将接收到的字节序列解释为Windows-1252字符集中的所有字符。
如果是这种情况,在继续任何进一步操作之前,您应该修复您的数据!
如果与现有编码不同,请将这些列转换为数据插入时使用的字符编码:

ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET foo;

通过将这些列转换为fos_user.username字符集,删除与这些列关联的编码信息:
ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET binary;

将数据实际传输的编码与这些列关联起来,将它们转换为相关的字符集。
ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET bar;

请注意,如果从多字节编码转换,可能需要增加列的大小(甚至更改其类型),以适应转换字符串的最大可能长度。
一旦确定列是正确编码的,就可以通过以下两种方式强制使用Unicode排序规则进行比较:-
显式将值latin1转换为Unicode字符集:
WHERE CONVERT(fos_user.username USING utf8) = ?

强制字符串文字具有比列更低的强制值(将导致列值隐式转换为utf-8):
WHERE fos_user.username = ? COLLATE utf8_general_ci

或者,如您所说,可以将列永久转换为Unicode编码并适当设置排序规则。
对于我的所有表,我可以手动将排序规则更改为binary而不需要任何复杂/预防措施吗?
主要考虑的是Unicode编码比单字节字符集占用更多空间,因此:
可能需要更多的存储空间;
比较可能较慢;以及
可能需要调整索引前缀长度(请注意,最大值以字节为单位,因此表示的字符可能比以前少)。
另外,请注意,如fos_user.username Syntax中所述:
要将表默认字符集和所有字符列(utf8_general_ciALTER TABLECHAR)更改为新字符集,请使用如下语句:
将表tbl_name转换为字符集charset_name;
对于数据类型为VARCHAR或其中一个TEXT类型的列,VARCHAR将根据需要更改数据类型,以确保新列足够长,可以存储与原始列一样多的字符。例如,TEXT列有两个长度字节,存储列中值的字节长度,最大值为65535。对于CONVERT TO CHARACTER SETTEXT列,每个字符需要一个字节,因此该列最多可以存储65535个字符。如果将列转换为latin1,则每个字符可能需要最多三个字节,最大可能长度为3×65535=19665字节。该长度不适用于TEXT列的长度字节,因此MySQL将数据类型转换为utf8,这是长度字节可以记录19665值的最小字符串类型。类似地,TEXT列可能会转换为MEDIUMTEXT
要避免对刚才描述的类型进行数据类型更改,请不要使用VARCHAR。相反,使用MEDIUMTEXT更改单个列。

关于mysql - MySQL非法混合排序规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12247120/

有关mysql - MySQL非法混合排序规则的更多相关文章

  1. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  2. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  3. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  4. ruby-on-rails - 在具有 ActiveRecord 条件的相关模型中按字段排序 - 2

    我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我

  5. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby​​目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin

  6. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  7. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi

  8. ruby - 如何测试正在使用 RSpec 和 Mocha 调用的混合类方法? - 2

    我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案

  9. ruby-on-rails - 在不重新查询数据库的情况下重新排序 Rails 中的事件记录? - 2

    例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果

  10. ruby-on-rails - 为什么 DataMapper 使用混合与继承? - 2

    所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass

随机推荐