小编典典

如何以编程方式确定表之间的MySQL关系类型(1:1、1:n,n:m)?

sql

我正在尝试查询一个MySQL服务器,以确定有关数据库的信息,以支持一些代码。

我已经非常成功地使用 Java JDBCINFORMATION_SCHEMA 表,但是问题是我需要确定表关系是
OneToOneOneToMany 还是 ManyToMany
。我找不到实现此目标的好方法,如果有人可以帮助我,并且如果有可能使用非特定于MySQL的可靠解决方案来帮助他人,我也很乐意。

编辑(更多) 为了进一步解释我的问题,我将添加更多信息。目前,我正在将MySQL与InnoDB和MySQL
Workbench一起使用来创建EER图并生成SQL以创建数据库。

我正在尝试对Java应用程序中的两个现有表之间的关系进行逆向工程,以确定一个表是 OneToOneOneToMany 还是
ManyToMany 。问题是,当我在MySQL Workbench中设计模型并创建两个表之间的关系时,即使它们的SQL输出相同,我也看不到Non-
Identifying 1:1和Non-Identifying 1:N之间没有任何区别。

非识别1:1

CREATE TABLE IF NOT EXISTS `TestDB`.`table1` (
  `var1` BIT(1) NOT NULL,
  `var2` BIT(8) NOT NULL,
  `var3` VARCHAR(45) NULL DEFAULT NULL,
  `var4` INT(11) NOT NULL,
  `table2_var1` INT(11) NOT NULL,
  PRIMARY KEY (`var1`, `var2`),
  INDEX `fk_table1_table2_idx` (`table2_var1` ASC),
  CONSTRAINT `fk_table1_table2`
    FOREIGN KEY (`table2_var1`)
    REFERENCES `TestDB`.`table2` (`var1`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci

非识别1:n

CREATE TABLE IF NOT EXISTS `TestDB`.`table1` (
  `var1` BIT(1) NOT NULL,
  `var2` BIT(8) NOT NULL,
  `var3` VARCHAR(45) NULL DEFAULT NULL,
  `var4` INT(11) NOT NULL,
  `table2_var1` INT(11) NOT NULL,
  PRIMARY KEY (`var1`, `var2`),
  INDEX `fk_table1_table2_idx` (`table2_var1` ASC),
  CONSTRAINT `fk_table1_table2`
    FOREIGN KEY (`table2_var1`)
    REFERENCES `TestDB`.`table2` (`var1`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci

当我使用MySQL Workbench反转数据库以查看它是否可以猜测它是 1:1 还是 1:n时
,最神奇的部分就来了,它实际上能够猜测它,图中具有正确的关系箭头!!!也许它将引用存储为唯一的引用,或者InnoDB在其自己的特定于供应商的INFORMATION_SCHEMA上具有此引用,但我想在我的应用程序中复制此行为。

关于如何实现此目标的任何想法?


阅读 240

收藏
2021-04-28

共1个答案

小编典典

经过进一步的研究,我发现尽管MySQL Workbench能够以某种方式对 1:11:n
关系进行逆向工程,即使当是引用外键的属性不是PK或UQ的非识别关系时,也可能对供应商特定的(InnoDB)属性执行操作。

*经过测试的 *所有 其他SQL逆向工程师工具都显示出非识别关系为OneToMany,即使它们在MySQL
WorkBench中被设计为OneToOne也是非识别的。假设我执行了一个JOIN查询,以检索必要的信息以将1:1与1:n区别开来,因此SQL如下所示:

“ table1”的示例

select INFORMATION_SCHEMA.COLUMNS.COLUMN_KEY, INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME, INFORMATION_SCHEMA.COLUMNS.TABLE_NAME from INFORMATION_SCHEMA.COLUMNS
join INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
on INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME=INFORMATION_SCHEMA.KEY_COLUMN_USAGE.COLUMN_NAME
where INFORMATION_SCHEMA.KEY_COLUMN_USAGE.TABLE_NAME='table1' 
and referenced_table_name is not null

最后…

伪代码

if (COLUMN_KEY == "PRI" || COLUMN_KEY == "UNI") { 
    //then you can assume is **OneToOne**
} else {
    //then you can assume is **OneToMany**
}

希望这对其他人有所帮助,可以随时添加任何建议或其他替代方法,谢谢大家。

2021-04-28