我试图查询MySQL服务器以确定有关数据库的信息,以便支持某些代码。
我使用 Java JDBC 和 INFORMATION_SCHEMA 表非常成功,但问题是我需要确定表关系是否为 OneToOne , OneToMany 或 ManyToMany 。我无法找到实现这一目标的好方法,如果有人可以帮助我,我会很高兴,如果有可能的解决方案不是MySQL特定的,那么它可以帮助其他人。
我在stackoverflow中发现了这个问题,但它不会解决问题: how-to-determine-cardinality-of-foreign-key-using-mysql
编辑(更多) 为了进一步解释我的问题,我将添加更多信息。目前,我正在使用带有InnoDB和MySQL Workbench的MySQL来创建EER图并生成SQL来创建数据库。
我试图在我的Java应用程序中对两个现有表格之间的关系进行逆向工程,以确定表格是 OneToOne , OneToMany 还是 ManyToMany 即可。问题是,当我在MySQL Workbench中设计模型并在两个表之间创建关系时,我发现非识别1:1和非识别1:N之间的任何差异甚至他们的SQL输出都是相同的
非识别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 时,出现了惊人的部分,它& #39; s实际上可以猜到它,图表有正确的关系箭头!也许它将引用存储在某个地方是唯一的,或者InnoDB在其自己的供应商特定的INFORMATION_SCHEMA上有这个,但我想在我的应用程序上复制这种行为。
我怎么能想到这个?
答案 0 :(得分:2)
经过进一步研究后,我发现虽然MySQL Workbench能够以某种方式对 1:1 和 1: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**
}
希望这有助于其他人的斗争,随时添加任何建议或替代方法,谢谢所有人。
答案 1 :(得分:1)
如果您有两个表格如下:
Table: a
a_id unique autoincrement primary key
a_info other information
和
Table: b
b_id unique autoincrement primary key
a_id a reference to a row in a
b_info other information
在此设计中,b
中每行a
中有一行,零行,一行或多行。对于a
中的每一行,b
中都有一行内容。这通常是 OneToMany 的意思。
如果表a_id
中的列b
恰好具有唯一索引,则b
中每行a
中只有一行或一行。Table: a
a_id unique autoincrement primary key
a_info other information
。这通常是指 OneToOne 。
如果关系是 ManyToMany ,则需要一个额外的表格,如下所示:
Table: b
b_id unique autoincrement primary key
b_info other information
和这张表
Table: a_b
a_id reference to a row in a
b_id reference to a row in b
由此表联系在一起
a_b
此关系表实现 ManyToMany 。它唯一的主键是两列的串联。
这是一个相当传统的设计;当您对现有模式进行逆向工程时,您应该能够选择它。要查找的是关系({{1}})样式表。