Error 1022 - No se puede escribir; clave duplicada en la tabla

218

Recibo un error 1022 con respecto a las claves duplicadas en el comando crear tabla. Después de mirar la consulta, no puedo entender dónde se produce la duplicación. ¿Alguien más puede verlo?

SQL query:

-- -----------------------------------------------------
-- Table `apptwo`.`usercircle`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS  `apptwo`.`usercircle` (

 `idUserCircle` MEDIUMINT NOT NULL ,
 `userId` MEDIUMINT NULL ,
 `circleId` MEDIUMINT NULL ,
 `authUser` BINARY NULL ,
 `authOwner` BINARY NULL ,
 `startDate` DATETIME NULL ,
 `endDate` DATETIME NULL ,
PRIMARY KEY (  `idUserCircle` ) ,
INDEX  `iduser_idx` (  `userId` ASC ) ,
INDEX  `idcategory_idx` (  `circleId` ASC ) ,
CONSTRAINT  `iduser` FOREIGN KEY (  `userId` ) REFERENCES  `apptwo`.`user` (
`idUser`
) ON DELETE NO ACTION ON UPDATE NO ACTION ,
CONSTRAINT  `idcategory` FOREIGN KEY (  `circleId` ) REFERENCES  `apptwo`.`circle` (
`idCircle`
) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB;

MySQL said: Documentation

#1022 - Can't write; duplicate key in table 'usercircle' 
Git-able
fuente
44
Si no recuerdo mal, la clave principal siempre es también un ÍNDICE ÚNICO, por lo que tendría que descartar la declaración de índice única.
Mr47
1
ON DELETE NO ACTIONsimplemente eliminaría el uso completo de la clave externa. A menos que tenga razones muy específicas para hacerlo.
AmazingDreams
44
@AmazingDreams ¿Por qué? Todavía impone integridad referencial. Solo tienes que eliminar a los niños tú mismo. Esto es más seguro que una eliminación en cascada en la que accidentalmente podría eliminar muchos datos al eliminar una palabra clave incorrecta.
GolezTrol
1
stackoverflow.com/a/5810024/1567737 ¿Por qué usar un alias cuando se usa 'alias' deja claro el propósito de inmediato?
AmazingDreams
@AmazingDreams Gracias por la sugerencia. También me gusta el debate en torno a esto: me ayuda a conocer los pros y los contras.
Git-able

Respuestas:

534

Lo más probable es que ya tenga una restricción con el nombre idusero idcategoryen su base de datos. Simplemente cambie el nombre de las restricciones si es así.

Las restricciones deben ser únicas para toda la base de datos, no solo para la tabla específica que está creando / alterando.

Para averiguar dónde se usan actualmente las restricciones, puede usar la siguiente consulta:

SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE `CONSTRAINT_NAME` IN ('iduser', 'idcategory');
Maksym Polshcha
fuente
15
Exactamente como dijiste. Muchas restricciones se generaron automáticamente con los mismos nombres de idcategory iduser en el resto de la consulta CREATE. ¡Gracias por su ayuda!
Git-able
1
Pensé que MySQL Workbench habría solucionado esto al exportar el script de creación, pero eso es lo que obtengo por "Ignorar" la advertencia sobre este tipo de cosas cuando abrí el proyecto.
SnowInferno
Gracias, amigo :) Eso me ayuda mucho y ahora mi convención para las claves foráneas es diferente y no puedo resolver este problema de nuevo :)
Puede confirmar eso. Pero, ¿qué puedo hacer si la restricción nombrada existe aunque la tabla referenciada ya se eliminó? ¿Puedo eliminar una restricción de una tabla no existente? Creo que debería actualizar MySQL 5.6 a MariaDB actual.
Anse
3
Gracias por esto: las restricciones deben ser únicas para toda la base de datos
sebasira
31

Cambie el nombre de la clave externa en MySQL. No puede tener los mismos nombres de clave externa en las tablas de la base de datos.

Verifique todas sus tablas y todas sus claves foráneas y evite tener dos claves foráneas con el mismo nombre exacto.

Wassim Sabra
fuente
Ese fue el problema en mi caso. Nunca lo habría adivinado y me salvaste el día. Usando fk_id_1, fk_id_2, etc., ahora. Gracias.
JackLeEmmerdeur
15

De los dos enlaces resueltos con éxito y convención de nomenclatura , resolví fácilmente este mismo problema que enfrenté. es decir, para el nombre de la clave externa, dé como fk _colName_ TableName . Esta convención de nomenclatura no es ambigua y también hace que cada ForeignKey en su modelo de base de datos sea única y nunca obtendrá este error.

Error 1022: no se puede escribir; clave duplicada en la tabla

Chandz
fuente
6

Como otros han mencionado, es posible que el nombre de su restricción ya esté en uso por otra tabla en su base de datos . Deben ser únicos en la base de datos.

Una buena convención para nombrar restricciones de clave externa es:

fk_TableName_ColumnName

Para investigar si hay un posible choque, puede enumerar todas las restricciones utilizadas por su base de datos con esta consulta:

SELECT * FROM information_schema.table_constraints WHERE constraint_schema = 'YOUR_DB';

Cuando ejecuté esta consulta, descubrí que previamente había hecho una copia temporal de una tabla y esta copia ya estaba usando el nombre de restricción que estaba tratando de usar.

Simon East
fuente
4

Acabo de pasar las últimas 4 horas con el mismo problema. Lo que hice fue simplemente asegurarme de que las restricciones tuvieran nombres únicos.

Puede cambiar el nombre de las restricciones. Agregué un número al mío para poder rastrear fácilmente el número de ocurrencias.

Ejemplo

Si una restricción en una tabla se llama boy con una clave externa X La siguiente restricción con la clave externa X se puede llamar boy1

Estoy seguro de que descubrirías mejores nombres que yo. 🙂

Guión desconocido
fuente
3

Esto también puede surgir en relación con un error en ciertas versiones de la herramienta de cambio de esquema en línea de Percona Toolkit. Para mutar una tabla grande, pt-osc primero crea una tabla duplicada y copia todos los registros en ella. En algunas circunstancias, algunas versiones de pt-osc 2.2.x intentarán dar a las restricciones de la nueva tabla los mismos nombres que las restricciones de la tabla anterior.

Se lanzó una solución en 2.3.0.

Consulte https://bugs.launchpad.net/percona-toolkit/+bug/1498128 para obtener más detalles.

MJD
fuente
1

También encontré ese problema. Verifique si el nombre de la base de datos ya existe en Mysql y cambie el nombre del anterior.


fuente
1

Tuve este problema al crear una nueva tabla. Resulta que el nombre de la clave externa que le di ya estaba en uso. Cambiar el nombre de la clave lo arregló.

usuario3076750
fuente