Различие MySQL между e и é (e sharp) - УНИКАЛЬНЫЙ индекс
У меня есть таблица students
с тремя столбцами: 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);
который работает нормально. Чем я пробовал этот (см. Ане - острый):
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:
Я изменил для использования collation utf8_bin:
ALTER TABLE `students`
CHARACTER SET utf8 COLLATE utf8_bin;
но я получаю ту же ошибку.
Но если я создам таблицу с начала с charset utf8 и collation 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
Это кажется очень странным.
Далее отредактируйте 2:
Я увидел здесь еще один ответ. Я не уверен, что пользователь удалился или он потерялся.
Я просто тестировал его:
Пользователь написал, что сначала создал 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 - должен что-то сделать с этим?! Даже я так не думаю.
Ответы
Ответ 1
и сортировка - "utf8_general_ci".
И это ответ. Если вы используете utf8_general_ci
(фактически это относится ко всем utf_..._[ci|cs]
), то диакритики обходят в коммарине, таким образом:
SELECT "e" = "é" AND "O" = "Ó" AND "ä" = "a"
Результаты в 1
. Индексы также используют сортировку.
Если вы хотите различать ą
и a
, используйте utf8_bin
сопоставление (помните, что он также различает символы верхнего и нижнего регистра).
Кстати, имя и возраст не гарантируют уникальности.
Ответ 2
Я обнаружил, что
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" )
Ответ 3
Изменить сортировку на latin1_german2_ci
checkout эффекты сортировки
Ответ 4
Я знаю, что этот вопрос несколько устарел, но мне нужно было удалить первичный ключ на моей таблице и вместо этого использовать обычный индекс. Похоже, что MySQL не выполняет сортировку utf8_bin в первичных ключах. Я использую MySQL 5.5.