4

我有一个 InnoDB MySQL 数据库,其中一个表需要能够通过外键连接到其他 26 个表之一。每条记录一次只能连接到这 26 条记录中的一条。该表可能包含不超过 10,000 条记录。有没有其他方法可以做到这一点?

-- -----------------------------------------------------
-- Table `db_mydb`.`tb_job`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `db_mydb`.`tb_job` (
  `job_id` INT(11) NOT NULL AUTO_INCREMENT ,
  // Removed 26 other fields that the table requires

  `job_foreignkey_a_id` INT(11) NULL DEFAULT NULL ,
  `job_foreignkey_b_id` INT(11) NULL DEFAULT NULL ,
  `job_foreignkey_c_id` INT(11) NULL DEFAULT NULL ,
  // Removed the other 23 foreign keys fields that are the same

  PRIMARY KEY (`job_id`) ,

  CONSTRAINT `fka_tb_job_tb`
    FOREIGN KEY (`job_foreignkey_a_id` )
    REFERENCES `db_mydb`.`tb_foreignkey_a` (`foreignkey_a_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fkb_tb_job_tb`
    FOREIGN KEY (`job_foreignkey_b_id` )
    REFERENCES `db_mydb`.`tb_foreignkey_b` (`foreignkey_b_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fkc_tb_job_tb`
    FOREIGN KEY (`job_foreignkey_c_id` )
    REFERENCES `db_mydb`.`tb_foreignkey_c` (`foreignkey_c_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
  // Removed the other 23 foreign keys constraints that are the same

ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

CREATE INDEX `fka_tb_job_tb` ON `db_mydb`.`tb_job` (`job_foreignkey_a_id` ASC) ;
CREATE INDEX `fkb_tb_job_tb` ON `db_mydb`.`tb_job` (`job_foreignkey_b_id` ASC) ;
CREATE INDEX `fkc_tb_job_tb` ON `db_mydb`.`tb_job` (`job_foreignkey_c_id` ASC) ;
// Removed the other 23 foreign keys indexes that are the same
4

3 回答 3

3

这就是泛型外键的问题,MySQL和朋友们往往不支持。有两种方法可以做到这一点。

正如您所做的那样,第一个是可为空的外键,每种类型都有一个。

另一个,如在 Django 中Content Types,是有一个连接表,每一行都有一个行 id 和一个指定要查找的表的字段。然后,您的代码必须根据字段的内容制定 SQL 查询。它运行良好,但有局限性:

第一个的缺点是臃肿,但它为您带来了普通 FK 的优点,即引用完整性和 SQL 连接等,这两者都非常有价值。你不能用第二种方法得到那些。

于 2013-01-04T14:57:25.597 回答
1

取决于您是否要维护外键约束,您可以拥有一张通过键或表类型引用其中一张表的表。问题是您将失去外键约束。当然,如果您可以创建基于函数的约束,那么它可以为您工作。或者,您可以使用触发器强制执行关系。基于函数的约束在 mysql 中不可用。

于 2013-01-04T15:03:49.670 回答
0

是的,你可以这么做。这两个 StackOverflow 答案在稍微不同的上下文中说明了基本原理。

使用 MySQL,您需要用外键引用替换关键的 CHECK() 约束。这不适用于 MySQL 的最一般情况,但它确实适用于这个特定的应用程序。

如果这些信息不足以让您继续前进,请给我留言,我将尝试进一步扩展此答案。

于 2013-01-04T15:35:15.197 回答