简体   繁体   English

在 mysql 中,删除级联不起作用

[英]in mysql, on delete cascade not working

similar to ON DELETE CASCADE not working in MySQL , but something is not right:类似于ON DELETE CASCADE not working in MySQL ,但有些地方不对:

The ANSI Way ANSI方式

-- test delete cascade
CREATE TABLE t1(
    id SERIAL PRIMARY KEY,
    data TEXT
);

CREATE TABLE t2(
    id INT PRIMARY KEY REFERENCES t1(id) ON DELETE CASCADE,
    data2 TEXT
);

INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t2 VALUES(1, 'first');

DELETE FROM t1;
SELECT * FROM t2; -- should have not rows - have one!

use this all the time in postgres, but for some reason cannot get it going in mysql.使用这一切Postgres的时间,但由于某种原因不能让它在MySQL中去。


I am slowly learning, there is the ansi-standard, postgreql way, and there is the mysql way.慢慢学习,有ansi-standard,postgreql方式,也有mysql方式。 Each time I think I have somewhat appreciated the difference, I haven't come close.每次我认为我有点欣赏这种差异时,我都没有接近。

The MySQL Way MySQL方式

CREATE TABLE `t2` (
    `id` BIGINT(20) UNSIGNED NOT NULL,
    `data2` TEXT,
    PRIMARY KEY (`id`),
    CONSTRAINT `FK_t2_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = latin1;

To me, the code I have is ansi standard, makes perfect sense, and is (as far as SQL goes) aesthetically pleasing, whereas, the mysql way (thanks for the help!) reminds me of Visual Basic or something - it's really ugly as sin and imho it's wrong to ask intelligent people to debase themselves to write such a thing.对我来说,我拥有的代码是 ansi 标准的,非常有意义,并且(就 SQL 而言)在美学上令人愉悦,而 mysql 方式(感谢您的帮助!)让我想起了 Visual Basic 或其他东西——它真的很丑作为罪孽和恕我直言,要求聪明的人贬低自己来写这样的东西是错误的。

I apologize if ranting, and justly deserve any number of negative ratings.如果咆哮,我深表歉意,理所当然地应该得到任何数量的负面评价。 You guys who write this code with ease have my greatest respect.你们轻松地编写了这段代码,这是我最大的敬意。 I just hate to see this sort of meaningless punishment inflicted on friends ;-)我只是讨厌看到这种对朋友施加的毫无意义的惩罚;-)

If you create t2 like this it works fine:如果你像这样创建 t2 它工作正常:

CREATE TABLE  `t2` (
  `id` bigint(20) unsigned NOT NULL,
  `data2` text,
  PRIMARY KEY (`id`),
  CONSTRAINT `FK_t2_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ETA, in answer to concerns about ugly code, the below also works: ETA,为了解决对丑陋代码的担忧,以下也有效:

CREATE TABLE  t2 (
  id bigint(20) unsigned NOT NULL PRIMARY KEY,
  data2 text,
  CONSTRAINT  FOREIGN KEY (id) REFERENCES t1(id) ON DELETE CASCADE
) ENGINE=InnoDB ;

The main difference is that the data type for t2.id must match that of t1.id and constraints have to be declared after the columns.主要区别在于 t2.id 的数据类型必须与 t1.id 的数据类型匹配,并且必须在列之后声明约束。

(assuming that should be a "foreign key" not a "primary key" in table t2) (假设应该是表 t2 中的“外键”而不是“主键”)

MySQL simply ignores all inline foreign key constraints without a warning. MySQL 只是在没有警告的情况下忽略所有内联外键约束。

Therefore, you need to explicitly add a foreign key constraint as shown by dnagirl.因此,您需要显式添加外键约束,如 dnagirl 所示。

Set the foreign_key_checks to 1, I ran into this problem while exporting and importing the data during which it was set to 0将foreign_key_checks设置为1,我在导出和导入设置为0的数据时遇到了这个问题

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1 */;

This happens because the default storage engine 'MyISAM' does not support foreign keys!发生这种情况是因为默认存储引擎“MyISAM”不支持外键!

Simply set the engine to InnoDB and make the referencing and referenced columns definition of both tables are matched.只需将引擎设置为 InnoDB,并使两个表的引用和被引用列定义匹配。

And this is an example:这是一个例子:

CREATE TABLE `students` (
  `id` INT AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `age` TINYINT NOT NULL,
  PRIMARY KEY(`id`)
) ENGINE=InnoDB CHARSET=latin1;

CREATE TABLE `marks` (
  `student_id` INT PRIMARY KEY,
  `mark` DECIMAL(5,2) NOT NULL,
  CONSTRAINT marks_FK_1 FOREIGN KEY(`student_id`) REFERENCES students(`id`) ON DELETE CASCADE
) ENGINE=InnoDB CHARSET=latin1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM