Creating a Foreign Key constraint with multiple fields in MySQL innodb
I have two tables: invoices & invoice_items. I need a one to many relationship between the two with cascading delete (so if the invoice is deleted, the items also get deleted).
The primary key开发者_运维知识库 on invoices spans two columns: invoice_number, vendor_number
The primary key on invoice_items spans three columns: invoice_number, vendor_number, item_number
How do I add a foreign key constraint to the invoice_items table using the invoice_number & vendor_number columns?
I tried this and it didn't work:
ALTER TABLE `invoice_items`
ADD FOREIGN KEY (`invoice_number`,`vendor_number`)
REFERENCES `invoices`(`invoice_number`,`vendor_number`) ON DELETE CASCADE;
ERROR 1005 (HY000): Can't create table 'test_db.#sql-12c8_db1ad' (errno: 150)
Here are the table definitions:
CREATE TABLE IF NOT EXISTS `invoices` (
`vendor_number` varchar(20) NOT NULL,
`invoice_number` varchar(20) NOT NULL,
`po_number` varchar(50) NOT NULL,
`inbound_message_id` int(11) NOT NULL,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`vendor_number`,`invoice_number`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `invoice_items` (
`vendor_number` varchar(20) NOT NULL,
`invoice_number` varchar(20) NOT NULL,
`po_item_number` varchar(6) NOT NULL,
`quantity` float NOT NULL,
`amount` decimal(10,2) NOT NULL COMMENT 'Total amount invoiced for this line item',
PRIMARY KEY (`vendor_number`,`invoice_number`,`po_item_number`),
KEY `invoice_key` (`vendor_number`,`invoice_number`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Here is the output from show innodb status:
110707 12:26:19 Error in foreign key constraint of table test_db/#sql-12c8_dcbfb:
FOREIGN KEY (`invoice_number`,`vendor_number`)
REFERENCES `invoices`(`invoice_number`,`vendor_number`) ON DELETE CASCADE:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Use show innodb status
. This will dump out a large block of text. In the middle somewhere is a "last foreign key error". It'll contain more details as to why the alter table failed.
One possibility is a mismatch in field types. The keyed fields must be exact duplicates in both tables. You can't link a signed field to an unsigned one, or a int to a bigint, etc...
精彩评论