我已经阅读了无数关于这个的线程,我仍然错过了一些东西。当我从表中删除一行时,没有约束或级联发生。
我的目标是级联删除所有子行。
CREATE SCHEMA IF NOT EXISTS `my_schema`
DEFAULT CHARACTER SET latin1;
USE `my_schema`;
SET foreign_key_checks = 0;
DROP TABLE IF EXISTS `test_types`;
DROP TABLE IF EXISTS `test_core_types`;
SET foreign_key_checks = 1;
-- -----------------------------------------------------
-- Table `test_core_types`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test_core_types` (
`test_core_type_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`data` VARCHAR(100) NOT NULL,
PRIMARY KEY (`test_core_type_id`))
ENGINE = InnoDB
AUTO_INCREMENT = 1;
CREATE UNIQUE INDEX `test_core_types__data_UNIQUE` ON `test_core_types` (`data` ASC);
-- -----------------------------------------------------
-- Table `test_types`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `test_types` (
`test_type_id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
`test_core_type_id` INT(10) UNSIGNED NOT NULL,
`name` VARCHAR(45) NOT NULL,
`is_viewable` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
PRIMARY KEY (`test_type_id`))
ENGINE = InnoDB
AUTO_INCREMENT = 1;
CREATE UNIQUE INDEX `test_types__name_UNIQUE` ON `test_types` (`name` ASC);
CREATE INDEX `idx_test_core_type_00` ON `test_types` (`test_core_type_id` ASC);
ALTER TABLE `test_types`
ADD CONSTRAINT `fk_test_core_type_00`
FOREIGN KEY (`test_core_type_id`)
REFERENCES `test_core_types` (`test_core_type_id`)
ON DELETE CASCADE
ON UPDATE NO ACTION;
插入:INSERT INTO `test_core_types` (`test_core_type_id`, `data`) VALUES ( 1, 'General');
INSERT INTO `test_types` (`test_type_id`, `test_core_type_id`, `name`, `is_viewable`) VALUES ( 1, 1, 'My General Item', 1);
删除:
DELETE FROM `test_core_types` WHERE `test_core_type_id` = 1;
结果:SELECT * FROM `test_core_types`;
/* --> Row Deleted */
SELECT * FROM `test_types`;
/* --> Row still exists */
当我执行删除时,行被删除,没有错误。
理论:
对于您的子表(test_types
),您提到了ON DELETE CASCADE
;这意味着当你从父表(test_core_types
)删除一行;同样的删除也会级联到子表,并且子表中相应的相关行也会被删除。
在你的delete query之后;如果您尝试从两个表中选择,您将发现0行。这是ON DELETE CASCADE
的实际行为。
对于实际示例,请查看下面提到的小提琴链接
http://sqlfiddle.com/!2/33014e/1
您指定的DELETE
规则为CASCADE
。
我们期望从父表中删除会成功,表中具有外键引用的相关行也将被删除。我们不希望出现任何错误。
如果您希望代码中的DELETE操作抛出错误,那么使用RESTRICT
的DELETE规则定义外键引用。
我建议您验证FOREIGN_KEY_CHECKS
是否启用,并且外键约束是否实际定义(即添加约束的ALTER TABLE语句是否成功)。我从来没有尝试指定NO ACTION
作为更新规则;我知道当没有指定规则时,这是默认的,但我总是指定RESTRICT
, CASCADE
或SET NULL
。)还要验证表是否实际使用了InnoDB存储引擎。
SHOW VARIABLES LIKE '%foreign_key_checks%' ;
SHOW CREATE TABLE `test_types` ;