2014-09-29 54 views
2

我想查詢一個MySQL服務器以確定有關數據庫的信息,以支撐一些代碼。如何以編程方式確定表之間的MySQL關係類型(1:1,1:n,n:m)?

我一直很成功使用的Java JDBCINFORMATION_SCHEMA表這一點,但問題是,我需要確定一個表關係OneToOne一對多多對多。我無法找到實現這一目標的好方法,如果有人能夠幫助我一點,並且如果可能的解決方案不是MySQL特有的,並且可以幫助其他人,我也會很樂意。

我發現這個問題的計算器,但它不會解決問題: how-to-determine-cardinality-of-foreign-key-using-mysql

EDIT(更多) 爲了進一步說明我的問題,我會添加更多的信息。目前我使用InnoDB和MySQL Workbench來創建EER圖並生成SQL來創建數據庫。

我試圖反向工程在我的Java應用程序中現有的兩個表之間的關係,以確定是否一個表是OneToOne一對多多對多。問題是,當我在MySQL Workbench中設計模型時,我在兩個表之間創建了一個關係,但我看不到Non-Identifying 1:1和Non-Identifying 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工作臺,看看數據庫它可以猜測它是否是一個1:11:n,它實際上能夠猜到它,圖有正確的關係箭!也許它將引用存儲爲唯一的地方,或者InnoDB在自己的供應商特定的INFORMATION_SCHEMA上有這個引用,但我想在我的應用程序中複製這種行爲。

任何想法,我怎麼能做到這一點?

回答

1

進一步研究後,我發現,雖然莫名其妙的MySQL Workbench是能夠反向工程1:11:偶數n關係時是一個非確定關係,其中引用的外鍵ISN」屬性t PK或UQ,這可能適用於特定於供應商(InnoDB)的屬性。

ALL其他經過測試的SQL反向工程師工具顯示出與OneToMany無關的關係,即使他們在MySQL WorkBench中設計爲OneToOne無法識別。假設這我預製一個JOIN查詢來檢索必要的信息來區分1:1 1:N 所以SQL變爲如下所示:

實施例關於「表1」

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

如果你有兩個表如下:

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 

有本質上,在這個設計中,零個,一個或多個行中ba每一行。對於b中的每一行,在a中固有地存在單行。這通常意味着OneToMany

如果表b中的a_id列恰好具有唯一索引,則中的每一行都有b中的零或一行。這通常是由OneToOne

如果關係是多對多,則需要額外的表,如下所示:

Table: a 
a_id unique autoincrement primary key 
a_info other information 

,這表

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 

此關係表實現ManyToMany。其獨特的主鍵是其兩列的連接。

這是一個相當傳統的設計;您應該能夠在對現有模式進行逆向工程時挑選出來。要尋找的是關係(a_b)樣式表。

+0

我最初認爲** OneToOne **和** OneToMany **之間的主要可見區別是@OllieJones在前面的答案中指出的,外鍵引用(在本例中爲** a_id **在**表b **)被標記或標記爲UQ(唯一),但令我驚訝的是,在InnoDB中使用MySQL工作臺時,我發現1:1和1:N都沒有標記爲UQ,而當我做反向該數據庫使用MySQL工具,它以某種方式設法檢測1:1和1:N之間的差異。我想知道在這種情況下如何處理這個問題。 感謝您的時間和精力奧利瓊斯 – Lethe 2014-09-29 16:34:37

相關問題