MySQL различие между е и е (е острый) - УНИКАЛЬНЫЙ индекс - PullRequest
16 голосов
/ 24 июня 2011

У меня есть таблица, students, с 3 столбцами: id, name и age.У меня есть UNIQUE индекс Index_2 для столбцов name и age.

CREATE TABLE `bedrock`.`students` (  
    `id` INTEGER UNSIGNED NOT NULL
    AUTO_INCREMENT,   `name` VARCHAR(45)
    NOT NULL,   `age` INTEGER UNSIGNED NOT
    NULL,   PRIMARY KEY (`id`),   UNIQUE
    INDEX `Index_2` USING BTREE(`name`,
    `age`) ) ENGINE = InnoDB;

Я попробовал этот параметр вставки:

insert into students (id, name, age)
values (1, 'Ane', 23);

, который работает нормально.Чем я пробовал этот (см. Ané - e острый ):

insert into students (id, name, age)
values (2, 'Ané', 23);

, и я получаю это сообщение об ошибке:

"Duplicate entry 'Ané-23' for key 'Index_2'"

MySQL почему-то не делает различий между «Ane» и «Ané».Как я могу решить эту проблему и почему это происходит?

Кодировка для учеников за столом - "utf8", а сопоставление - "utf8_general_ci".

ALTER TABLE `students` CHARACTER SET utf8 COLLATE utf8_general_ci;

Позже edit1: @Crozin:

Я перешел на использование сортировки utf8_bin:

ALTER TABLE `students`
CHARACTER SET utf8 COLLATE utf8_bin;

, но получаю ту же ошибку.

Но если я создаю таблицу с начала с набором символовutf8 и параметры сортировки utf8_bin, например:

CREATE TABLE `students2` ( 
`id` INTEGER UNSIGNED AUTO_INCREMENT, 
`name` VARCHAR(45),   `age`
VARCHAR(45),   PRIMARY KEY (`id`),  
UNIQUE INDEX `Index_2` USING
BTREE(`name`, `age`) ) ENGINE = InnoDB
CHARACTER SET utf8 COLLATE utf8_bin;

обе нижеприведенные команды вставки работают нормально:

insert into students2 (id, name, age)
values (1, 'Ane', 23); // works ok

insert into students2 (id, name, age)
values (2, 'Ané', 23); // works ok

Это кажется очень странным.

Позжеedit 2:

Я видел другой ответ здесь.Я не уверен, что пользователь удалил или он потерялся.Я просто тестировал его:

Пользователь написал, что сначала он создал 3 таблицы с 3 различными кодировками:

CREATE TABLE `utf8_bin` (   `id`
int(10) unsigned NOT NULL
AUTO_INCREMENT,   `name` varchar(45)
COLLATE utf8_bin NOT NULL,   `age`
int(10) unsigned NOT NULL,   PRIMARY
KEY (`id`),   UNIQUE KEY `Index_2`
(`name`,`age`) USING BTREE )
ENGINE=InnoDB DEFAULT CHARSET=utf8
COLLATE=utf8_bin;

CREATE TABLE `utf8_unicode_ci` (  
`id` int(10) unsigned NOT NULL
AUTO_INCREMENT,   `name` varchar(45)
COLLATE utf8_unicode_ci NOT NULL,  
`age` int(10) unsigned NOT NULL,  
PRIMARY KEY (`id`),   UNIQUE KEY
`Index_2` (`name`,`age`) USING BTREE )
ENGINE=InnoDB DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci;

CREATE TABLE `utf8_general_ci` (  
`id` int(10) unsigned NOT NULL
AUTO_INCREMENT,   `name` varchar(45)
COLLATE utf8_general_ci NOT NULL,  
`age` int(10) unsigned NOT NULL,  
PRIMARY KEY (`id`),   UNIQUE KEY
`Index_2` (`name`,`age`) USING BTREE )
ENGINE=InnoDB DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

Результаты пользователя:

Insert commands: INSERT INTO utf8_bin
VALUES (1, 'Ane', 23), (2, 'Ané', 23);
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

INSERT INTO utf8_unicode_ci VALUES (1,
'Ane', 23), (2, 'Ané', 23); Query OK,
2 rows affected (0.01 sec) Records: 2 
Duplicates: 0  Warnings: 0

INSERT INTO utf8_general_ci VALUES (1,
'Ane', 23), (2, 'Ané', 23); Query OK,
2 rows affected (0.01 sec) Records: 2 
Duplicates: 0  Warnings: 0

Вот мои результаты:

INSERT INTO utf8_bin VALUES (1, 'Ane',
23), (2, 'Ané', 23);        //works ok
INSERT INTO utf8_unicode_ci VALUES (1,
'Ane', 23), (2, 'Ané', 23); //
Duplicate entry 'Ané-23' for key
'Index_2'

INSERT INTO utf8_general_ci VALUES (1,
'Ane', 23), (2, 'Ané', 23);
//Duplicate entry 'Ané-23' for key
'Index_2'

Я не уверен, почему в его части эта INSERT команда сработала, а у меня не работает.

Он также написал, что тестировалэто на Mysql на Linux - что-то делать с этим ?!Даже я так не думаю.

Ответы [ 4 ]

14 голосов
/ 24 июня 2011

и сопоставление "utf8_general_ci".

И это ответ.Если вы используете utf8_general_ci (на самом деле это относится ко всем utf_..._[ci|cs]) сопоставлениям, тогда диакритические знаки обойдутся в комбинации, таким образом:

SELECT "e" = "é" AND "O" = "Ó" AND "ä" = "a"

В результате 1.В индексах также используется сопоставление.

Если вы хотите различать ą и a, тогда используйте сопоставление utf8_bin (имейте в виду, что оно также различает прописные и строчные буквы).


Кстати, имя и возраст не гарантируют никакой уникальности.

5 голосов
/ 22 октября 2013

Я обнаружил, что

ALTER TABLE students CHARACTER SET utf8 COLLATE utf8_bin;

у меня не сработало, так как не изменило параметры сортировки существующих столбцов, как видно из результатов этого запроса:

SHOW FULL COLUMNS from students;

Однако следующий запрос выполнил задание и преобразовал существующие столбцы в сопоставление utf8_bin:

ALTER TABLE students CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

(обратите внимание на "CONVERT TO")

2 голосов
/ 22 мая 2012

Я знаю, что этот вопрос сейчас несколько устарел, но мне пришлось удалить первичный ключ из моей таблицы и использовать вместо него обычный индекс.Кажется, что MySQL не соблюдает параметры сортировки utf8_bin в первичных ключах.Я использую MySQL 5.5.

2 голосов
/ 24 июня 2011

Изменить параметры сортировки на latin1_german2_ci

оформить заказ эффекты сопоставления

...