Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Unicode和排序规则方面,如何让MySQL像SQLite一样处理字符串?_Mysql_Unicode_Collation - Fatal编程技术网

在Unicode和排序规则方面,如何让MySQL像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

我已经在MySQL文档和其他地方研究这个问题好几个小时了,但仍然找不到满意的解决方案。问题是:

让MySQL像SQLite一样处理字符串,而不进行任何额外的“智能”转换,最简单的方法是什么?

例如,以下内容在SQLite中非常有效:

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
    是正确的选择

  • MySQL允许以列级粒度设置编码和排序的组合

  • 如果列定义缺少排序规则,它将使用表级别1

  • 如果表定义缺少排序规则,它将使用数据库级别1

  • 如果数据库定义缺少排序规则,它将使用服务器级别1

  • 还值得注意的是,MySQL将在编码之间进行透明转换,只要:

    • 连接编码设置正确
    • 转换在物理上是可能的(例如,所有源字符也属于目标编码)
    出于最后一个原因,
    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值时,不考虑任何 尾随空格。本上下文中的“比较”不包括 与模式匹配运算符类似,尾随空格为 重要的

    [……] 对于删除或删除尾随字符的情况 比较忽略它们,