Cannot add foreign key constraint MySQL Workbench - mysql

I'm getting "Error Code: 1215. Cannot add foreign key constraint" when trying to create the "orders" table.
credit_cards table:
CREATE TABLE credit_cards (
customer VARCHAR(30),
card_no CHAR(16),
PRIMARY KEY (customer, card_no),
FOREIGN KEY (customer) REFERENCES customers(username));
orders table:
CREATE TABLE orders (
order_no INT AUTO_INCREMENT,
customer VARCHAR(30) NOT NULL,
date_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
credit_card CHAR(16) NOT NULL,
PRIMARY KEY (order_no),
FOREIGN KEY (customer)
REFERENCES customers (username),
FOREIGN KEY (credit_card)
REFERENCES credit_cards (card_no));
The report from SHOW ENGINE INNODB STATUS says that the problem is FOREIGN KEY (credit_card) REFERENCES credit_cards(card_no))
I've read a bunch of resolved questions and still can't figure it out. I'm using MySQL Workbench. Thanks.

You need to reference all the keys in a primary key (or unique key) relationship. I would recommend:
CREATE TABLE credit_cards (
credit_card_id int auto_increment primary key,
customer VARCHAR(30),
card_no CHAR(16),
UNIQUE KEY (customer, card_no),
FOREIGN KEY (customer) REFERENCES customers(username));
orders table:
CREATE TABLE orders (
order_no INT AUTO_INCREMENT,
customer VARCHAR(30) NOT NULL,
date_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
credit_card_id int NOT NULL,
PRIMARY KEY (order_no),
FOREIGN KEY (customer)
REFERENCES customers (username),
FOREIGN KEY (credit_card_id)
REFERENCES credit_cards (credit_card_id));

Related

i am trying to create foreign keys but i got error 1822 .. please see my code below

CREATE TABLE employee(
empid int auto_increment primary key,
empfirstname varchar(200) not null,
emplastname varchar(200) not null,
email varchar(200) not null,
officenumber int not null
);
CREATE TABLE customer(
custid int auto_increment primary key,
firstname varchar(200) not null,
lastname varchar(200) not null,
address varchar(200) not null,
contact varchar(200)
);
CREATE TABLE product(
productid int auto_increment primary key,
productdesc varchar(500) not null,
weight int not null,
unit_cost int not null
);
CREATE TABLE productorder(
productid int,
orderid int,
primary key(productid,orderid),
constraint fk3 foreign key (productid) references product(productid),
constraint fk4 foreign key (orderid) references productorder(orderid)
);
CREATE TABLE salesorder(
salesorderid int auto_increment primary key,
empid int not null,
custid int not null,
orderdate date not null,
shippingmethod varchar (200) not null,
constraint a_fk1 foreign key (empid) references employee(empid),
constraint a_fk2 foreign key (custid) references customer(custid)
);
What is this meant to do?:
constraint fk4 foreign key (orderid) references productorder(orderid)
It's not uncommon for a table to have a foreign key back to its own primary key, such as for records which have a parent/child relationship. But that doesn't seem to be the case here.
More to the point of the error though, this isn't referencing the entire primary key for the target table. That key has two fields:
primary key(productid,orderid)
So the DBMS can't create the foreign key because its structure doesn't match the target primary key.
If you want to create that foreign key, it would need to match. Probably something like this:
constraint fk4 foreign key (productid,orderid) references productorder(productid,orderid)
But it doesn't appear that you need that foreign key at all, because it doesn't seem to make sense in your data model. Instead I suspect orderid might need to be autoincrement and just use the productid foreign key. Something like this:
CREATE TABLE productorder(
orderid int auto_increment primary key,
productid int,
constraint fk3 foreign key (productid) references product(productid)
);
(Note that there could be more changes you'd want to make to your data model. This answer doesn't purport to provide you with a complete production-ready data model, just to correct the error. Your data model is likely to change/evolve as you develop your system.)
Its normal,
The foreign key in table **productorder**
is refereing to the table itself:
constraint fk4 foreign key (orderid) references **productorder**(orderid)
In order to achieve the self-referencing constraint on the table productorder, you need to add another column with the same type and make typical referencing.
For instance :
Create table productorder (
productid int,
orderid int,
orderid_parent int,
primary key(productid,orderid),
constraint fk_self foreign key(orderid) references productorder(orderid_parent)
)

How to define Many to Many linking table

I have a schema with a store and product table. A store record, may have many products, and a product may be available to many stores (many to many) To link these, a third table has the PRIMARY KEY of the store, and product records. Should this linking table, have a compound PRIMARY KEY? Or, should this simply be two FOREIGN KEYS, each with an INDEX()?
CREATE TABLE store(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
PRIMARY KEY(id)
) ENGINE=INNODB;
CREATE TABLE product(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
PRIMARY KEY(id)
) ENGINE=INNODB;
So, should the linking table be like..
CREATE TABLE store_product_link(
store_id INT NOT NULL,
product_id INT NOT NULL,
INDEX(store_id),
INDEX(product_id),
FOREIGN KEY (store_id) REFERENCES store(id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES product(id) ON DELETE CASCADE
) ENGINE=INNODB;
Or should this be
CREATE TABLE store_product_link(
store_id INT NOT NULL,
product_id INT NOT NULL,
PRIMARY KEY(store_id, product_id)
) ENGINE=INNODB;
Both, it should have a primary key and both foreign keys.
CREATE TABLE store_product_link(store_id INT NOT NULL, product_id INT NOT NULL,
PRIMARY KEY(store_id, product_id),
FOREIGN KEY (store_id) REFERENCES store(id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES product(id) ON DELETE CASCADE) ENGINE=INNODB;

can't add foreign key constraint in mysql

create table buys (
user_id INT(11) not null,
software_id INT(11) not null,
associated_id INT(11) not null,
primary key (associated_id),
foreign key (software_id) references software,
foreign key (user_id) references users,
foreign key (associated_id) references associated);
I have a ternary relationship associated table having total participation and a key constraint but cannot add foreign key constraints
Check the following query:
CREATE TABLE products(
prd_id int not null auto_increment primary key,
cat_id int not null,
FOREIGN KEY fk_cat(cat_id)
REFERENCES categories(cat_id)
)ENGINE=InnoDB;
In your case:
foreign key (software_id) references software -> here column name is missing in software table

MySQL: Creating a table that with a foreign key that references a primary key made up of foreign keys

I have a table of books, which stores book IDs and titles, authors, etc., a table of customers which has customer IDs (PK), customer name, birthday. Then there is a table of transactions, which includes the BookId and the CustomerID as foreign keys. The primary key of this transaction table is the two foreign key columns.
The problem is now I am creating a table of book ratings based on transactions which have occurred (So a customer can't rate a book they don't own, or the same book twice.). This table must contain the bookID, the customerID, and the rating info. I'm trying to constrain the table so that each bookID and customerID row must reference an existing row in the transaction table. However, none of the constraints I've tried so far work. Any help at all would be greatly appreciated.
Here's my tables at the moment:
CREATE TABLE eBook
( BookTitle VARCHAR(50),
BookID CHAR(13) NOT NULL,
BookPub CHAR(4) NOT NULL,
BookDate DATE NOT NULL,
BookHard BOOL NOT NULL,
BookSize INT NOT NULL,
CONSTRAINT PKBookID PRIMARY KEY (BookID)
);
CREATE TABLE customer
( CustID CHAR(9) NOT NULL,
CustSSN CHAR(11) NULL,
CustName VARCHAR(50) NOT NULL,
CustBirth INT(4) NOT NULL,
CONSTRAINT PKCustID PRIMARY KEY (CustID),
CONSTRAINT UniqSSN UNIQUE (CustSSN)
);
CREATE TABLE Buys
( BuysID CHAR(5) NOT NULL
BookID CHAR(13) NOT NULL,
CustID CHAR(9) NOT NULL,
TransDate DATETIME NOT NULL,
Price DECIMAL(5,2) NOT NULL,
CONSTRAINT FK1 FOREIGN KEY (BookID) REFERENCES eBook (BookID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK2 FOREIGN KEY (CustID) REFERENCES customer (CustID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT PKBuys PRIMARY KEY (BookID, CustID)
);
CREATE TABLE Rating
( BookID CHAR(13) NOT NULL,
CustID CHAR(9) NOT NULL,
RatingID CHAR(5) NOT NULL,
Rating INT(1) NOT NULL,
RatingDate DATE NOT NULL,
CONSTRAINT FK13 FOREIGN KEY (BookID, CustID) REFERENCES buys (BookID, CustID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT PKRating PRIMARY KEY (RatingID)
);
You already have a foreign key on your Rating table that should constrain Rating rows each to correspond to a Buys row. I suppose that the problem must be with your other objective, that customers cannot rate the same book twice. With respect to that, I guess you have a misconception about foreign keys: they have to be unique on the target table, but they do not automatically have to be unique on the referring side.
To prevent multiple Rating rows having the same combination of BookID and CustomerID, you need an additional UNIQUE constraint on the Rating table, naming those columns. Alternatively, you could give the Rating table a composite primary key consisting of those columns. Either way, you'll have separate constraints, one establishing the uniqueness of those columns in the referring table, and the other constraining them to pairs that appear in the Buys table.
You can create a multi column foreign key reference as documented on http://dev.mysql.com/doc/refman/5.0/en/create-table-foreign-keys.html
That should do the trick.
Your sample code contains an error. You are missing a (,) in the Buys table.
CREATE TABLE eBook
( BookTitle VARCHAR(50),
BookID CHAR(13) NOT NULL,
BookPub CHAR(4) NOT NULL,
BookDate DATE NOT NULL,
BookHard BOOL NOT NULL,
BookSize INT NOT NULL,
CONSTRAINT PKBookID PRIMARY KEY (BookID)
);
CREATE TABLE customer
( CustID CHAR(9) NOT NULL,
CustSSN CHAR(11) NULL,
CustName VARCHAR(50) NOT NULL,
CustBirth INT(4) NOT NULL,
CONSTRAINT PKCustID PRIMARY KEY (CustID),
CONSTRAINT UniqSSN UNIQUE (CustSSN)
);
CREATE TABLE Buys
( BuysID CHAR(5) NOT NULL,
BookID CHAR(13) NOT NULL,
CustID CHAR(9) NOT NULL,
TransDate DATETIME NOT NULL,
Price DECIMAL(5,2) NOT NULL,
CONSTRAINT FK1 FOREIGN KEY (BookID) REFERENCES eBook (BookID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK2 FOREIGN KEY (CustID) REFERENCES customer (CustID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT PKBuys PRIMARY KEY (BookID, CustID)
);
CREATE TABLE Rating
( BookID CHAR(13) NOT NULL,
CustID CHAR(9) NOT NULL,
Rating INT(1) NOT NULL,
RatingDate DATE NOT NULL,
CONSTRAINT FK13 FOREIGN KEY (BookID, CustID) REFERENCES buys (BookID, CustID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT PKRating PRIMARY KEY (BookID, CustID)
);
When using this corrected ddl, the tables are created just fine.
I've created some test data
insert into `ebook`(`BookTitle`,`BookID`,`BookPub`,`BookDate`,`BookHard`,`BookSize`) values ('grey','1','ME','2015-02-06',1,10);
insert into `customer`(`CustID`,`CustSSN`,`CustName`,`CustBirth`) values ('1','daCust','Cust',1974);
insert into `buys`(`BuysID`,`BookID`,`CustID`,`TransDate`,`Price`) values ('1','1','1','2015-02-06 00:00:00',10.00);
insert into `rating`(`BookID`,`CustID`,`RatingID`,`Rating`,`RatingDate`) values ('1','1','1',1,'2015-02-06');
Now adding the following data will result in an error due to the foreign key constraint.
insert into `rating`(`BookID`,`CustID`,`RatingID`,`Rating`,`RatingDate`) values ('7','3','1',1,'2015-02-06');
To ensure that the user can add only one rating per book you should add a unique constraint on the fields BookID and CustID or set those fields as primary key. In the working code example above i have added those fields as primary key and removed the obsolete RatingID.

How to make a foreign key from a composite key?

I want to make a foreign key from a primary key and got this error '#1005 - Can't create table'
Here is the DDL used...
CREATE TABLE Invoice
(
InvoiceID SMALLINT,
TaskID SMALLINT,
FOREIGN KEY Invoice(InvoiceID) REFERENCES XTABLE(InvoiceID),
PRIMARY KEY (InvoiceID, TaskID)
);
Make sure the key columns in XTABLE and Invoice are marked as the PRIMARY KEY and NOT NULL.
CREATE TABLE XTABLE(InvoiceID SMALLINT NOT NULL, PRIMARY KEY(InvoiceID));
CREATE TABLE Invoice (
InvoiceID SMALLINT NOT NULL,
TaskID SMALLINT NOT NULL,
PRIMARY KEY (InvoiceID, TaskID),
CONSTRAINT FOREIGN KEY Invoice(InvoiceID) REFERENCES XTABLE(InvoiceID)
);
SQL FIDDLE: http://sqlfiddle.com/#!2/5a56f