2013-03-21 46 views
18

我有很少的表,我想從PDF表中引用一列到多個其他表。 enter image description here有可能引用一列作爲多個外鍵

例如,如果PDF表格select輸出看起來是這樣的:

ITEM_TYPE ITEM_ID QUANTITY 

1   23  3 
2   12  1 

它告訴我:

PDF有3個汽車輪產品,以及1汽車模板上面頭;

我寫的SQL代碼,但不能正常工作:

CREATE TABLE `pdf_created` (
    `id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, 
    `pdf_id` INT(10) NOT NULL, 
    `item_type` INT(3) UNSIGNED NOT NULL, 
    `item_id` INT(10) UNSIGNED NOT NULL, 
    `quantity` INT(3) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `FK_pdf_id` (`pdf_id`), 
    CONSTRAINT `FK_pdf_id` FOREIGN KEY (`pdf_id`) REFERENCES `pdf` (`id`), 
    KEY `FK_item_type` (`item_type`), 
    CONSTRAINT `FK_item_type` FOREIGN KEY (`item_type`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
    KEY `FK_item_id` (`item_id`), 
    CONSTRAINT `FK_item_id` FOREIGN KEY (`item_id`) REFERENCES `product` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT `FK_item_id` FOREIGN KEY (`item_id`) REFERENCES `service` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT `FK_item_id` FOREIGN KEY (`item_id`) REFERENCES `header` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE `header` (
    `id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, 
    `title` VARCHAR(255), 
    `desc` VARCHAR(65535), 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE `service` (
    `id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, 
    `desc` VARCHAR(65535) NOT NULL, 
    `price` DECIMAL(5,2) NOT NULL, 
    `active` INT(1) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE `product` (
    `id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, 
    `category_id` INT(3) UNSIGNED NOT NULL, 
    `symbol` VARCHAR(255), 
    `desc` VARCHAR(65535), 
    `price` DECIMAL(5,2) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

有可能創造呢?

+0

不,這是不可能的。您的外鍵必須指向一個表,它不能指向帶有外鍵的table1,table2或table3。 您可以在插入之前和更新觸發器之前檢查它是否存在於其中一個表 – 2013-03-21 12:20:29

+0

Michael中,令人驚訝的是,某些DBMS可能在相同的字段上定義N> 1個外鍵並將它們指向不同的表。我剛剛在MySQL 5.5,Oracle 11g和MS SQL 2012中證實了這一點。我認爲使用該功能幾乎總是一個壞主意,但這不是不可能的(並且在多個表被引用爲父母都是同一個邏輯實體)。請參閱http://stackoverflow.com/questions/19057188​​/one-field-with-two-references-in-mysql/19057571#19057571 – 2013-09-30 12:47:02

回答

19

也就是說,您不能通過這種方式創建外鍵約束。但是,您可以使用沒有外鍵約束的外鍵。

所有外鍵是,是另一個表(或同一個表中的另一個記錄)主鍵的值,它可以在連接中使用。事實上,如果您只需要使用連接的值,則可以引用主鍵以外的字段。

但是,外鍵約束告訴數據庫強制執行規則,即對於表中的每個外鍵值,被引用的表都有一條記錄,因爲它是主鍵。強制PDF表中的每個外鍵都有一個主鍵在所有四個表中都不適用於您。因此,請繼續並使用該字段來引用其他記錄,但不要創建任何外鍵約束。

+0

還要注意,UML和更多標準的表格組織結構的標準方法是將一個虛線框作爲可能表格的父項,帶有空白三角形的「箭頭」作爲箭頭從可能的表格指向虛線框,並具有從PDF表格到虛線框的正常箭頭。 – 2013-03-21 14:01:07

+0

OK,現在它看起來像:'CREATE TABLE'pdf_created'( \t'id' INT(10)UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, \t'pdf_id' INT(10)UNSIGNED NOT NULL, \t'item_type' INT( 3)UNSIGNED NOT NULL, \t'item_id' INT(10)UNSIGNED NOT NULL, \t'quantity' INT(5)UNSIGNED NOT NULL, \t PRIMARY KEY('id') \t外鍵('pdf_id' )參考'pdf'('id'), \t FOREIGN KEY('item_type')REFERENCES'item'('id') )ENGINE = InnoDB DEFAULT CHARSET = utf8;' – insict 2013-03-21 14:02:18

+0

我不是su您是否想要或需要「FOREIGN KEY(pdf_id)REFERENCES pdf(id)」,但它看起來不錯。 – 2013-03-21 14:20:25

1

應該有可能。一個潛在的問題是您的三個外鍵約束具有相同的名稱。

1

不,一個外鍵字段是用來引用一個表的。

如果您確實具有FK約束,item_id字段將在所有三個表中引用相同的主鍵值。三個不同表中所需的主鍵很可能具有不同的主鍵。

你想要的是一條記錄(行)引用記錄在表格Product,Header和Service中。要做到這一點的方法是使用三個不同的字段,每個外鍵一個。

我還注意到Item項有需要三個外鍵。您可以讓PDF表格有一個引用Item的字段,Item中的記錄引用另外三個表格。

+0

我想過它,但這將意味着總是有兩列(Product,Header,服務)將是空的。 – insict 2013-03-21 12:34:05

+0

產品的一號外鍵將具有產品表中主鍵的值。一個引用Header的外鍵字段將在Header表中具有主鍵的值。一個引用Service的外鍵字段將具有Service中主鍵字段的值。考慮PDF是否使用了Product中的主鍵33,Header中的57以及Service中的82。您不能將這三個主鍵值存儲在一個字段中。 – 2013-03-21 12:39:01

+0

ok,但此表具有'數量'列,所以此項目不能放在一行中 – insict 2013-03-21 12:51:48

0

ya其可能的外鍵約束名稱應與此不同 ,主鍵和外鍵表列應具有相同的數據類型,如下所示。

CREATE TABLE `neo_address_t` (
    `address_id` varchar(8) NOT NULL, 
    `address_line_1` varchar(45) NOT NULL, 
    `address_line_2` varchar(45) NOT NULL, 
    `address_line_3` varchar(45) NOT NULL, 
    `address_city` varchar(45) NOT NULL, 
    `address_zipcode` varchar(45) NOT NULL, 
    `address_state` varchar(45) NOT NULL DEFAULT 'Karnataka', 
    `address_country` varchar(45) NOT NULL DEFAULT 'INDIA', 
    `created_by` varchar(8) DEFAULT NULL, 
    `created_on` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `last_modified_by` varchar(8) DEFAULT NULL, 
    `last_modified_date` timestamp NULL DEFAULT '0000-00-00 00:00:00', 
    `Refer_ID` int(11) DEFAULT NULL, 
    `a_id` varchar(255) DEFAULT NULL, 
    `referenceid` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`address_id`), 
    KEY `hospital_ID_FK_idx` (`Refer_ID`), 
    CONSTRAINT `Patient_ID_FK` FOREIGN KEY (`Refer_ID`) REFERENCES `neo_patient_t` (`patient_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    CONSTRAINT `hospital_ID_FK` FOREIGN KEY (`Refer_ID`) REFERENCES `neo_hospital_t` (`hospital_id`) ON DELETE NO ACTION ON UPDATE CASCADE, 
    CONSTRAINT `staff_ID_FK` FOREIGN KEY (`Refer_ID`) REFERENCES `neo_staff_t` (`staff_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION 
)  
ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 
0

理論上你不能強制執行單列多個外鍵。 或者,您可以使用驗證多表中存在的輸入並執行必要操作的過程來強制執行此操作。 請注意,該特定表上的所有操作都應該通過驗證所需條件的過程來完成,否則會導致違反完整性。

相關問題