2013-03-21 90 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

理论上你不能强制执行单列多个外键。 或者,您可以使用验证多表中存在的输入并执行必要操作的过程来强制执行此操作。 请注意,该特定表上的所有操作都应该通过验证所需条件的过程来完成,否则会导致违反完整性。