MySQL:在唯一的复合键集上删除级联

标签 mysql database innodb foreign-key-relationship cascade

我已经研究这个问题好几个小时了,我很惊讶我没有找到可靠的答案。一定有人做这件事。也许我一直在搜索错误的关键字。

所以,我使用 MySQL、InnoDB(当然),因为我的问题与外键和关系有关。

我想做的是构建一个 ON DELETE CASCADE 定义。

如您所见,我的表“test_i18n”有一个复合主键,由 test_i18n_id 和 test_locale 构建。这些本身都不是独一无二的。但他们在一起,形成了独特的一对。

我们将此称为表 A。

CREATE TABLE IF NOT EXISTS `test_i18n` (
  `test_i18n_id` int(11) NOT NULL AUTO_INCREMENT,
  `test_locale` enum('en','zh') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'en',
  PRIMARY KEY (`test_i18n_id`,`test_locale`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

我现在有另一张 table 。对于表 A 中的每个唯一对,我可以添加与表 A 相关的一条或多条记录。

我们将此称为表 B。

CREATE TABLE IF NOT EXISTS `test_i18_link` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `test_i18_id` int(11) NOT NULL,
  `locale` enum('en','zh') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'en',
  PRIMARY KEY (`id`),
  UNIQUE KEY `test_i18_id` (`test_i18_id`,`locale`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

这只是一些测试数据。

INSERT INTO `test_i18n` (`test_i18n_id`, `test_locale`) VALUES
(1, 'en'),
(1, 'zh'),
(2, 'en'),
(2, 'zh');

INSERT INTO `test_i18_link` (`test_i18_id`, `locale`, `url`) VALUES
(1, 'en', 'http://www.google.com'),
(2, 'en', 'http://www.yahoo.com');

现在,我想要实现的是,如果我从表 A 中删除第一条记录 (1, 'en'),那么表 B 中的第一条记录 (1, 1, 'en') 将自动被级联删除。

但是,另一方面,如果我从表 A 中删除第二条记录 (1, 'zh'),则表 B 中不会删除任何内容,因为表 B 中不存在这样的唯一对。

现在,在回答之前,我想强调一个重要的观点。

我确实注意到,这可以通过向表 A 添加一个 PK 列并让表 B 引用该新列而不是复合键集来完成。但由于种种原因我没能这么做。我想看看是否有一种方法可以真正正确地实现这一目标。

提前谢谢大家!

干杯, 托马斯

最佳答案

不幸的是,对于这种结构,经过无数个小时的研究和思考,目前这是不可能的,除非有一些前沿的东西随 MySQL 的下一版本一起发布。

因此,您在数据库级别可以做的最好的事情是,就像我最初在问题中提到的那样:

  • 向表 A 添加一个 PK 列,并让表 B 引用该新列而不是复合键集。

关于MySQL:在唯一的复合键集上删除级联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29298597/

相关文章:

php - 无法将 php 变量保存到 mysql 数据库或文件

mysql - RESTful web 服务 : java. lang.NullPointerException service.AbstractFacade.findAll

php - 我对 mysql 数据库的数据库设计模式正确吗?

php - 我怎样才能将数据库中的项目存储到数组中,但前提是该项目不在数组中?

mysql - 如何在 MySQL 中将字符串转换为日期?

java - 用按钮单击时的查询替换 jtable 中的先前行 - java swing

database - 为 Flask Web 应用程序存储和检索许多小文本文档的最佳方式是什么

MySQL Innodb : Large Composite PK no other indexes

MySQL - 在初始 auto_increment 值之前保留 ID

mysql - 在巨大的 InnoDB 表上优化 DROP TABLE