MySQL InnoDB - 将父级链接到两个子级之一的键的约束

标签 mysql key constraints innodb

使用 MySQL,从 MyISAM 迁移到 InnoDB 表。数据库设计从转储数据并在没有外键或约束的情况下重新导入数据开始。一次添加一个以查找错误。

我有 ParentTable,它可以链接到 ChildTableAChildTableB,但不能同时链接到两者。 CREATE 语法应该是:(为了简单起见,使用 CREATE 语法而不是多个 ALTER)

CREATE TABLE `ParentTable`
   `IDParentTable` bigint(20) unsigned NOT NULL auto_increment,
   `IDChildTableA` bigint(20) unsigned NOT NULL default '0',
   `IDChildTableB` bigint(20) unsigned NOT NULL default '0',
   PRIMARY KEY (`IDParentTable`),
   KEY `ParentTable_IDChildTableA` (`IDChildTableA`),
   KEY `ParentTable_IDChildTableB` (`IDChildTableB`)
ENGINE=InnoDB DEFAULT CHARSET=latin1;

不假思索,我尝试包括:

CONSTRAINT `ParentTable_IDChildTableA` FOREIGN KEY (`IDChildTableA`) REFERENCES `ChildTableA` (`IDChildTableA`),
CONSTRAINT `ParentTable_IDChildTableB` FOREIGN KEY (`IDChildTableB`) REFERENCES `ChildTableB` (`IDChildTableB`)

失败了,因为 IDChildTableA 许多行的值为 0,IDChildTableB 许多行的值为 0。但是,没有行两者都为 0。可以看出,IDChildTableA 为 0 时不存在 ChildTableA,B 也同样如此。

是否有适当的方法来处理这种情况,同时保持引用完整性?不将 ParentTable 一分为二?有没有办法说如果它是 0 或引用有效的相关表就可以?或者,想要多态表是否意味着我必须不受限制? 顺便说一句,我更喜欢这条路线,而不是有一个 IDChildTable 外键,然后有另一列指定它是表 A 还是 B...我认为这对于约束来说并不适用,只是说我宁愿不走那条路...

最佳答案

用作外键的列可以为空。在外键列中使用 NULL 值来指示“未引用行”。

你的外键好像装反了。通常,子表有对父表的引用。

parent (id int primary key) 

childA (id int,  parent_id int, ...)

childB (id int,  parent_id int, ...)
<小时/>

编辑

与引用两个表的外键列(基于鉴别器列)的问题相关......这是不可能的。一个外键约束只能引用一张表。

要实现类似的功能,您需要添加两个单独的外键列,每个外键列引用一个目标表。您可以利用额外的鉴别器列(A 或 B)来识别应使用哪个外键列,因此一个 fk 列将填充有引用,另一个 fk 列将设置为 NULL。

但是,不存在需要填充这两个 fk 列之一的声明性约束。数据库不会强制执行这一点。额外的鉴别器列实际上是多余的,因为您可以根据填充的外键列来派生它。

关于MySQL InnoDB - 将父级链接到两个子级之一的键的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18563564/

相关文章:

mysql - 如何在 JPA 中创建通用查询?

java - 在没有 keyPressed/Released 事件的情况下检查键的状态

java - 为什么 bean 验证 Min/Max 约束不支持 double 类型?

sql - 什么时候在 SQL Server 2005 中限制联接是有利的?

mysql - 使用复合键在 GORM 中对现有数据库关系建模

mysql - LIMIT 子查询 MySQL 的最佳解决方法

php - 通过扩展的 php 生成 4 位 token

php - 总结一列中的所有数量

python - 迭代 Python 字典中的嵌套键并在第一次出现时中断

ssh - 如何使ssh使用不同的id_dsa