我有一张下面结构的表格:
CREATE TABLE `Lm_help` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`section` int(10) NOT NULL,
`language` int(10) NOT NULL,
`title` varchar(255) NOT NULL,
`text` text NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_help` (`section`,`language`),
KEY `language_constraint` (`language`),
CONSTRAINT `language_constraint` FOREIGN KEY (`language`) REFERENCES `Lm_languages` (`id`),
CONSTRAINT `section_constraint` FOREIGN KEY (`section`) REFERENCES `Lm_help_sections` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
我需要删除“unique_help”键,但我收到了外键约束错误。
由于此错误,我无法删除其中的任何内容, section_constraint,language_constraint,unique_help。
以下是其他表格:
CREATE TABLE `Lm_languages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`code` varchar(255) NOT NULL,
`status` int(11) DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1
CREATE TABLE `Lm_help_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
答案 0 :(得分:19)
问题是unique_help (section, language)
外键约束使用了section_constraint
索引。因此,在不先删除约束的情况下,不能删除索引。
解决此问题的一种方法是首先删除外键约束,然后删除索引。
然后,您可以在(section)
上添加(简单)索引并重新创建外键。
所有这些都可以在一个声明中完成:
ALTER TABLE Lm_help
DROP FOREIGN KEY section_constraint, -- drop the FK so
DROP INDEX unique_help, -- the index can be dropped
-- and then
ADD INDEX section_IX (section), -- add a new index
ADD CONSTRAINT section_FK -- so the FK can be recreated
FOREIGN KEY (section)
REFERENCES Lm_help_sections (id)
;
进行测试
<强>改进强>
我错了,不需要删除并重新创建约束。只要创建了新索引,就可以删除索引:
ALTER TABLE Lm_help
DROP INDEX unique_help,
ADD INDEX section_IX (section)
;
进行测试
答案 1 :(得分:7)
ALTER TABLE Orders
DROP FOREIGN KEY 'language_constraint';
ALTER TABLE Orders
DROP FOREIGN KEY 'section_constraint';
执行此处删除查询
ALTER TABLE Orders
ADD CONSTRAINT `language_constraint`
FOREIGN KEY (`language`)
REFERENCES `Lm_languages` (`id`);
ALTER TABLE Orders
ADD CONSTRAINT `section_constraint`
FOREIGN KEY (`section`)
REFERENCES `Lm_help_sections` (`id`);
答案 2 :(得分:2)
<击> As your error message suggests 击>
<击>(...)在 [由外键引用的表] 中,必须有一个 index将引用的列列为第一列的索引 同样的订单。
您必须找到引用表并从此(这些)其他表中删除外键约束。
击>
我很糟糕,我过快地读完你的表定义。实际问题是the other way around:
MySQL要求外键和引用键上的索引 外键检查可以很快,不需要进行表扫描。
首先删除section_constraint
外键约束,或者在删除UNIQUE约束之前在language
上创建一个新索引。
答案 3 :(得分:1)
这是一个存储过程,您可以在调用create sql之前调用该存储过程来删除外键。我修改了一个关于DROP PROCEDURE IF EXISTS回答的类似问题的答案:https://stackoverflow.com/users/166161/thomas-paine
示例电话:
CALL DropForeignKey (DATABASE(), 'tablename', 'keyname');
步骤:
DELIMITER ;
/* DROP_FOREIGN_KEY */
DROP PROCEDURE IF EXISTS DropForeignKey;
DELIMITER //
CREATE PROCEDURE DropForeignKey(
IN param_schema VARCHAR(100),
IN param_table_name VARCHAR(100),
IN param_constraint_name VARCHAR(100)
)
BEGIN
IF EXISTS(
SELECT NULL FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME=param_constraint_name AND TABLE_NAME=param_table_name AND TABLE_SCHEMA = param_schema
)
THEN
set @paramTable = param_table_name ;
set @ParamConstraintName = param_constraint_name ;
set @ParamSchema = param_schema;
/* Create the full statement to execute */
set @StatementToExecute = concat('ALTER TABLE `',@ParamSchema,'`.`',@paramTable,'` DROP FOREIGN KEY `',@ParamConstraintName,'` ');
/* Prepare and execute the statement that was built */
prepare DynamicStatement from @StatementToExecute ;
execute DynamicStatement ;
/* Cleanup the prepared statement */
deallocate prepare DynamicStatement ;
END IF;
END //
DELIMITER ;