在Unicode和排序规则方面,如何让MySQL像SQLite一样处理字符串?
我已经在MySQL文档和其他地方研究这个问题好几个小时了,但仍然找不到满意的解决方案。问题是: 让MySQL像SQLite一样处理字符串,而不进行任何额外的“智能”转换,最简单的方法是什么? 例如,以下内容在SQLite中非常有效:在Unicode和排序规则方面,如何让MySQL像SQLite一样处理字符串?,mysql,unicode,collation,Mysql,Unicode,Collation,我已经在MySQL文档和其他地方研究这个问题好几个小时了,但仍然找不到满意的解决方案。问题是: 让MySQL像SQLite一样处理字符串,而不进行任何额外的“智能”转换,最简单的方法是什么? 例如,以下内容在SQLite中非常有效: CREATE TABLE `dummy` (`key` VARCHAR(255) NOT NULL UNIQUE); INSERT INTO `dummy` (`key`) VALUES ('one'); INSERT INTO `dummy` (`key`) V
CREATE TABLE `dummy` (`key` VARCHAR(255) NOT NULL UNIQUE);
INSERT INTO `dummy` (`key`) VALUES ('one');
INSERT INTO `dummy` (`key`) VALUES ('one ');
INSERT INTO `dummy` (`key`) VALUES ('One');
INSERT INTO `dummy` (`key`) VALUES ('öne');
SELECT * FROM `dummy`;
但是,在MySQL中,使用以下设置:
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_bin
以及以下CREATE DATABASE
语句:
CREATE DATABASE `dummydb` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_bin;
它在第二次插入时仍然失败
我宁愿让字符串-列声明尽可能简单,SQLite的TEXT
是最理想的看起来VARBINARY
是一个不错的选择,但我还是想听听您对任何其他可能更好的选项的意见
附录:显示创建表虚拟输出为
mysql> SHOW CREATE TABLE dummy;
+-------+-----------------------------------------------------
| Table | Create Table
+-------+-----------------------------------------------------
| dummy | CREATE TABLE `dummy` (
`key` varchar(255) COLLATE utf8mb4_bin NOT NULL,
UNIQUE KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+-------+-----------------------------------------------------
1 row in set (0.00 sec)
MySQL希望在执行
INSERT
和SELECT
时转换字符串。转换是在声明客户机拥有的内容和声明列存储的内容之间进行的
避免这种情况的唯一方法是使用VARBINARY
和BLOB
而不是VARCHAR
和TEXT
使用排序规则utf8mb4_bin
不会避免与字符集utf8mb4
之间的转换;它只是说,WHERE
和orderby
应该比较位,而不是处理重音和大小写折叠
请记住,字符集utf8mb4
是对文本进行编码的一种方法<代码>排序规则utf8mb4*是比较该编码中文本的规则<代码>\u bin是简单的
UNIQUE
涉及到相等性的比较,因此排序规则
。在大多数utf8mb4排序规则中,3(不带空格)将比较相等<代码>utf8mb4_bin会将3视为不同的<代码>utf8mb4_匈牙利语_citreats one=one>
尾随空格由列的数据类型(
VARCHAR
或其他)控制。最新版本甚至有一个关于是否考虑尾随空间的设置。< P>问题中所示的方法应该(主要是)在MySQL中工作得很好,原因如下:
cafe
我也希望找到caf
)utf8mb4_-bin
是正确的选择- 连接编码设置正确
- 转换在物理上是可能的(例如,所有源字符也属于目标编码)
VARBINARY
可能不是仍然是文本的列的最佳选择,因为它打开了从配置为使用ISO-8859-1的连接获取café
存储的大门,并且无法从配置为使用UTF-8的连接中正确检索它
旁注:显示的表格定义可能会触发以下错误: 错误1071(42000):指定的密钥太长;最大密钥长度为767字节 索引的最大大小可能相对较小。发件人: 如果启用了innodb_large_前缀(默认),则索引键前缀 对于使用动态或压缩的InnoDB表,限制为3072字节 行格式。如果禁用innodb_large_前缀,则索引键前缀 对于任何行格式的表,限制为767字节 innodb_large_前缀已弃用,并将在将来删除 释放。MySQL 5.5中引入了innodb_large_前缀来禁用 大索引键前缀,与早期版本的兼容 不支持大索引键前缀的InnoDB InnoDB表的索引键前缀长度限制为767字节 使用冗余或压缩行格式。例如,您可能会 此限制在列上的列前缀索引超过255个字符 TEXT或VARCHAR列,假定为utf8mb3字符集和 每个字符最多3个字节 正在尝试使用超过限制的索引键前缀长度 返回一个错误。为避免复制配置中出现此类错误, 如果无法在主机上启用innodb_large_前缀,请避免启用该前缀 在从机上启用 由于utf8_mb8为每个字符分配4个字节,767限制将溢出192个字符
我们还有一个问题:
mysql> CREATE TABLE `dummy` (
-> `key` varchar(191) COLLATE utf8mb4_bin NOT NULL,
-> UNIQUE KEY `key` (`key`)
-> )
-> ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO `dummy` (`key`) VALUES ('one');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO `dummy` (`key`) VALUES ('one ');
ERROR 1062 (23000): Duplicate entry 'one ' for key 'key'
什么
mysql> INSERT INTO `dummy` (`key`) VALUES ('One');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO `dummy` (`key`) VALUES ('öne');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM `dummy`;
+-----+
| key |
+-----+
| One |
| one |
| öne |
+-----+
3 rows in set (0.00 sec)
最后一期是MySQL排序规则的一个有趣的细节。发件人:
所有MySQL排序规则都是PADSPACE类型。这意味着所有字符,
比较MySQL中的VARCHAR和TEXT值时,不考虑任何
尾随空格。本上下文中的“比较”不包括
与模式匹配运算符类似,尾随空格为
重要的
[……]
对于删除或删除尾随字符的情况
比较忽略它们,