MySQL:MySQL表中的两个不同值被视为相同(不能设置唯一键)

时间:2016-05-22 09:28:46

标签: mysql sql select collation cyrillic

我已经转储了我的小型MySQL表(手动缩小以解决问题)以在此处显示:

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;



CREATE TABLE `symb` (
  `smb` varchar(200) NOT NULL,
  `trtmnt` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `symb` (`smb`, `trtmnt`) VALUES
('і', 'ty'),
('ї', 'hr');


/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

如果您创建上面的MySQL表并运行此查询

select * from symb where smb = 'ї';

或者这个(查询不同 - 请参阅符号'Ê'与'і'

select * from symb where smb = 'і';

然后你可能会看到你选择了两行而不是我想要的一行。

要重新强调,上面这两个选择查询是不同的 - 符号'ї'与'і'不同(两者都是西里尔符号,'此处'不是拉丁语。)

Collation chosen was utf8_general_ci

为什么'і'和'ї'被视为相同的符号以及使它与众不同的正确方法有什么原因?我需要选择确切的行,而不是两行。

上面的查询在phpMyAdmin和HeidiSQL中进行了测试,这意味着是MySQL(校对?)问题,而不是用于运行查询的程序。 应将每个不同的符号视为不同的符号,并且表格应区分大小写。上面的表有什么问题?结果我无法为此行设置唯一键。

谢谢。

根据评论添加: SHOW TABLE STATUS LIKE'commb'向您展示了什么? 它告诉我:

Name    symb
Engine  InnoDB
Version 10
Row_format  Compact
Rows    2
Avg_row_length  8192
Data_length 16384
Max_data_length 0
Index_length    0
Data_free   0
Auto_increment  NULL
Create_time 22.05.16 12:11
Update_time NULL
Check_time  NULL
Collation   utf8_general_ci
Checksum    NULL
Create_options  
Comment 

4 个答案:

答案 0 :(得分:3)

这就是你选择的整理如何运作的方式。您可以在此处查看更多信息:https://stackoverflow.com/a/1036459/4099089

答案 1 :(得分:2)

由于您的SELECT语句正在返回两个记录,因此您的数据似乎已被错误地编码为UTF-8。因此,仅将smb列的编码从Latin1更改为UTF-8将不起作用。您可以选择将数据库转储为二进制文件,然后将其重新导入为UTF-8:

mysqldump --add-drop-table your_database | replace CHARSET=latin1 CHARSET=utf8 |
    iconv -f latin1 -t utf8 | mysql your_database

阅读herehere了解详情。

答案 2 :(得分:1)

你想要哪一个?

D197       1111=x0457  [ї]    L  CYRILLIC SMALL LETTER YI
C3AF        239=x00EF  [ï]    L  LATIN SMALL LETTER I WITH DIAERESIS

如果您执行SELECT col, HEX(col) ...,那么您应该获得正确存储D197C3AF的{​​{1}}或YI。这是判断它是否以utf8(或utf8mb4)正确存储的最佳方式。

他们看起来一样,但他们的待遇不同。所有的utf8 / utf8mb4校对将所有拉丁字母后的所有西里尔字母排序。

" best" "一般"整理是i-umlaut。 (utf8,而不是utf8mb4,如果你不需要中文或表情符号就没问题。)

Here是我对西欧角色在各种utf8 / utf8mb4校对中的比较的概述。例如,在所有其他utf8mb4_unicode_520_ci值之后,utf8_spanish2_ci是唯一一个将ll视为“单独字符”的字符。 utf8_latvian_ci将lĶ作为单独的字母处理。等

Ļ显示表格的默认;您需要查看SHOW TABLE STATUS以查看是否有任何列覆盖了该默认值。

答案 3 :(得分:0)

我已通过以下方式解决了这个问题:

1)将表格排序更改为utf8mb4_unicode_520_ci

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci

这允许您插入乌克兰字母表中的所有字母,除了ґ。 这也允许您按照预期的方式对字母进行排序。

2)将列整理更改为utf8mb4_bin

ALTER TABLE table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

这允许您插入ґ字符。

*这种方法的唯一缺点是,在排序时你必须使用

SELECT * FROM table_name ORDER BY column_name COLLATE utf8mb4_unicode_520_ci ASC

但是,它仍然不会对DESC进行排序