2011-06-24 12 views
16

Tengo una tabla, students, con 3 columnas: id, name y age. Tengo un UNIQUE índice Index_2 en las columnas name y age.distinción de MySQL entre e y é (agudo) - índice UNIQUE

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; 

yo probamos este opción de inserción:

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

que funciona bien. Lo que yo he intentado este (ver Ané - e aguda):

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

y recibo este mensaje de error:

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

MySQL alguna manera no hace ninguna distinción entre "Ane "y" Ané ". ¿Cómo puedo resolver esto y por qué está pasando esto?

Charset para estudiantes de tabla es "utf8" y la intercalación es "utf8_general_ci".

ALTER TABLE `students` CHARACTER SET utf8 COLLATE utf8_general_ci; 

tarde edit1: @Crozin:

he cambiado a utilizar el cotejo utf8_bin:

ALTER TABLE `students` 
CHARACTER SET utf8 COLLATE utf8_bin; 

pero recibo el mismo error.

Pero si creo la mesa desde el principio con utf8 y utf8_bin cotejo, de esta manera:

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; 

tanto por debajo comandos de inserción funciona bien:

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

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

Esto parece ser muy raro.

Más tarde editar 2:

vi otra respuesta aquí. No estoy seguro de si el usuario borró o se pierde. sólo estaba probando:

El usuario escribió que primero creó 3 mesas con 3 juegos de caracteres diferentes:

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; 

Los resultados del usuario son:

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 

Aquí están mis resultados :

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' 

No estoy seguro de por qué en su parte esteEl comandofuncionó y para mí no funciona.

También escribió que probó esto en Mysql en Linux, ¿tiene que hacer algo con esto? Incluso yo no lo creo

+0

No relacionado con su pregunta, pero nunca es una buena idea tener una clave única en un campo de nombre ... Muchas personas tienen el mismo nombre. ¿Qué planeas hacer en esa instancia? Dicho esto, el hecho de que haya creado una clave única basada en el nombre y la edad sugeriría una decisión de diseño ... –

+0

Hola Brendan, este es solo un ejemplo, uno ficticio, no es lo mismo que tengo en el proyecto ¡Trabajo! Sé que no está bien tener un índice único en columnas como 'nombre' y 'edad'. Elegí este ejemplo (no uno muy inteligente - I admin) en lugar de elegir el ejemplo real que contiene más de 10 columnas ... – Paul

+0

Eso tiene sentido. –

Respuesta

12

y la colación es "utf8_general_ci".

Y esa es la respuesta. Si está utilizando utf8_general_ci (en realidad se aplica a todos utf_..._[ci|cs]) de colación y luego se pasan por alto los signos diacríticos en comarison, por lo tanto:

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

Resultados en 1. Los índices también usan colación.

Si desea distinguir entre ą y luego usar autf8_bin cotejo (tener en cuenta que también distingue entre mayúsculas y minúsculas).


Por cierto, nombre y edad no garantizan ninguna singularidad.

+0

He respondido su pregunta actualizando la pregunta, no había suficiente espacio aquí. También agregué la parte "Editar más tarde 2". – Paul

+0

relacionado con "el nombre y la edad no garantizan ninguna singularidad", consulte mi segundo comentario para esta pregunta, en respuesta a Brendan. – Paul

+0

utilizando la intercalación 'utf_8 bin' funciona bien, el único problema que tengo es que distingue entre mayúsculas y minúsculas y no quería distinguir entre mayúsculas y minúsculas. ¿Conoces una solución para esto? Gracias. – Paul

2

Cambio de colación a latin1_german2_ci

la caja collation effects

+0

Votación negativa: 'utf8_unicode_ci' causará el mismo error. – Crozin

+0

@Shakti Singh: Usar la intercalación basada en latin en Unicode-encoded podría resolver un problema en este caso particular pero conduce a docenas de nuevos problemas. – Crozin

+0

@Shakti Singh: Todavía considero esto como una respuesta incorrecta. – Crozin

2

Sé que esta pregunta es algo antigua ahora, pero lo que tenía que hacer era eliminar la clave principal en mi tabla y usar un índice regular, en su lugar. Parece que MySQL no respeta la intercalación de utf8_bin en claves primarias. Estoy usando MySQL 5.5.

4

me encontré con que

ALTER TABLE students CHARACTER SET utf8 COLLATE utf8_bin; 

no funcionó para mí, ya que no se alteró la intercalación de las columnas existentes, como puede verse en los resultados de esta consulta:

SHOW FULL COLUMNS from students; 

Sin embargo, la siguiente consulta hizo el trabajo y convirtió las columnas existentes a la intercalación utf8_bin:

ALTER TABLE students CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; 

(noti ce el "CONVERTIR A")

Cuestiones relacionadas