2012-07-16 110 views
1

我想建立如下的數據庫場景:MySQL的 - 引用一個外鍵的多種可能的主鍵

CREATE TABLE IF NOT EXISTS `points` (
    `po_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `po_north` INT, 
    `po_east` INT, 
    PRIMARY KEY (`po_id`), 
) ENGINE=InnoDB; 

CREATE TABLE IF NOT EXISTS `lines`(
    `li_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `li_from` INT NOT NULL, 
    `li_to` INT NOT NULL, 
    PRIMARY KEY (`li_id`), 
    FOREIGN KEY (`li_from`) REFERENCES points(`po_id`), 
    FOREIGN KEY (`li_to`) REFERENCES points(`po_id`), 
) ENGINE=InnoDB; 

現在我想建立第三個表,那瘡喜歡誰創造了一些元數據或改變的一個點或線:

CREATE TABLE IF NOT EXISTS `metadata` (
    `me_type` ENUM('point','line') NOT NULL, 
    `me_type_id` INT UNSIGNED NOT NULL, 
    `me_permissions` VARCHAR(255) NOT NULL, 
    `me_created_by` INT UNSIGNED NOT NULL, 
    `me_created_on` DATETIME NOT NULL, 
    `me_last_modified_by` INT UNSIGNED NOT NULL, 
    `me_last_modified_by` DATETIME NOT NULL, 
) ENGINE=InnoDB; 

我的第一種方法是設置一個ENUM與兩種類型(點線)。但問題仍然是,我無法正確地將外鍵引用到其中一個表。 MySQL中有沒有推薦的解決方案?

BTW: me_created_byme_last_modified_by的字段應引用存儲一些用戶數據的表。

+0

您的表中的點和線可以引用元數據嗎,即將外鍵'metadata_id'放在這兩個表中? – 2012-07-16 11:06:10

回答

0

您的表格pointslines應該包含metadata的外鍵 - 而不是相反。這樣做可以避免您定義更復雜的表格設置。使用這種方法,單個metadata -entry可以多次重複使用多個不同的點或線。這甚至不是MySQL特有的,但是是一個通用的,規範化的數據庫結構。

+0

啊,我沒那麼想。這似乎是解決我的問題的最簡單的解決方案。謝謝 – mgr 2012-07-16 12:15:07

+0

@mgr這是關係數據庫中的「默認」方式。你應該閱讀[數據庫規範化](http://en.wikipedia.org/wiki/Database_normalization)。 – feeela 2012-07-16 12:25:05

-1

您可以使用觸發器做到這一點,你需要根據各自的表

你插入一條記錄之前觸發可以爲任何點或線創建基準關鍵事件
+0

我想mgr問的是如何構建數據庫模式,以便表可以在一個表或另一個不同的表中有一個主鍵字段的外鍵。或者你的意思是使用觸發器來檢查引用完整性而不是約束? – 2012-07-16 10:59:06

1

你的情況似乎是另一種情況被稱爲「泛化專業化」的設計模式或者「類繼承的表設計」。

如果將點和線想象爲對象類,它們都是一些更一般對象類的子類。在這種情況下,我不確定給這個超類命名的名字。以下是幾個解決同一問題的問題之一。

Extending classes in the database

福勒給出的主題的廣泛的治療。你的情況有一個額外的皺紋,因爲你正在處理元數據。但是這並不需要改變設計。你需要第三個表格,我將其稱爲「項目」,因爲缺乏更好的術語。關鍵字「it_id」將被分配一個自動編號,並且每次添加一個點或一行時,都會添加一個項目。兩列「po_id」和「li_id」不會被分配一個自動編號。相反,它們將是外鍵,在Items表中引用「it_id」。

對元數據表中的點或線的引用將是對「條目」的引用,您可以根據具體情況使用該信息來查找有關點或線的信息。

這是否有幫助取決於您想要對元數據進行的操作。

+0

這個解決方案對我來說很有意思,我會按照你的建議閱讀一些給定的文章。謝謝 – mgr 2012-07-16 12:18:17

相關問題