I'm trying to create a foreign key on two columns of a table to point to the same column of another table, but I seem to get an error...
Here's what I do:
CREATE TABLE test2 (
ID INT NOT NULL AUTO_INCREMENT,
col1 INT NOT NULL,
col2 INT NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk FOREIGN KEY (col1, col2)
REFERENCES test1(ID, ID)
ON UPDATE CASCADE
ON DELETE RESTRICT
) ENGINE=InnoDB;
But I get
ERROR 1005 (HY000): Can't create table 'DB.test2' (errno: 150)
If I only have one column, however, the table is correctly created.
Could someone point out to me where the error is?
Thanks
n
Tried it here and got the same error. This works though:
CREATE TABLE test2 (
ID INT NOT NULL AUTO_INCREMENT,
col1 INT NOT NULL,
col2 INT NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk FOREIGN KEY (col1)
REFERENCES test1(ID)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT fk2 FOREIGN KEY (col2)
REFERENCES test1(ID)
ON UPDATE CASCADE
ON DELETE RESTRICT
) ENGINE=InnoDB
Yes, I know - your script should work (even if it doesn't seem to make much sense). Yet, I guess this new version is better.
The problem would appear to be that you are specifying the same parent column twice in the same foreign key (i.e, (ID, ID)). The following should work:
Create Table Test1
(
PK1 int not null
, PK2 int not null
, Primary Key ( PK1, PK2 )
)
Create Table Test2
(
Id int not null Auto_Increment
, PK1 int not null
, PK2 int not null
, Primary Key ( ID )
, Constraint FK_Test2
Foreign Key ( PK1, PK2 )
References Test1( PK1, PK2 )
)
If it is the case, that you want two columns in a child table referencing the same parent table column, then you must add two foreign key references as shown by rsenna as those represent two independent relations.
Related
What I am doing incorrect? Trying to create these tables in sqlfiddle
does not work gives
Cannot add foreign key constraint
create table product (
pid int NOT NULL,
name varchar(10),
PRIMARY KEY (pid)
);
create table trans (
tid int NOT NULL ,
productId int NOT NULL,
userId int NOT NULL,
PRIMARY KEY (tid),
FOREIGN KEY (productId) REFERENCES product(pid),
FOREIGN KEY (userId) REFERENCES user1(uid)
);
create table user1 (
uid int NOT NULL ,
location varchar(22),
PRIMARY KEY (uid)
);
As #BillKarwin mentioned, the definitions for tables containing primary keys referenced by the trans table should appear before the definition for the trans table. So you should move the definition for the trans table to last.
However, even doing this still results in an error in SQLFiddle:
SQLFiddle (uncomment the foreign key reference in trans)
SQLFiddle seems to have some sort of problem with accepting this table schema. This is not surprising, as the site seems to have such problems frequently.
What is order you create tables. You need first to create product and user1 and at the end - trans.
I have 2 different tables: Profile and Transaction
Profile consists of: pID, firstName, lastName, phoneNumb
Transaction consists of: transID, sellerID, buyerID, itemID
My question is:
How to make sure that both sellerID and buyerID act as a foreign key in reference to profileID in Profile table?
My current code right now:
CREATE TABLE PROFILE
(
pID INT NOT NULL AUTO_INCREMENT ,
firstName VARCHAR(20) NOT NULL ,
lastName INT(20) NOT NULL ,
phoneNumb INT NOT NULL ,
PRIMARY KEY (pID)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE TRANSACTION
(
tID INT NOT NULL AUTO_INCREMENT ,
sellerID INT ,
buyerID INT,
itemID INT,
PRIMARY KEY (tID),
FOREIGN KEY (sellerID, buyerID) REFERENCES PROFILE(pID),
FOREIGN KEY (itemID) REFERENCES ITEM (itemID)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
I tried this and it gave me this kind of error
1239 - Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
Thanks.
I would go about it this way:
CREATE TABLE TRANSACTION
(
tID INT NOT NULL AUTO_INCREMENT,
sellerID INT,
buyerID INT,
itemID INT,
PRIMARY KEY (tID),
CONSTRAINT fk1 FOREIGN KEY (sellerID) REFERENCES PROFILE(pID)
CONSTRAINT fk2 FOREIGN KEY (buyerID) REFERENCES PROFILE(pID)
CONSTRAINT itemKey FOREIGN KEY (itemID) REFERENCES ITEM (itemID)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
This assumes that a table called ITEM exists which has a primary key called itemID. Your original problem mentioned only two tables. If ITEM does not exist, then either create it or remove the foreign key constraint from TRANSACTION.
I have already created a table in MySQL! And have tried a number of queries to alter the table and add foreign key to the table!
But none of them work??
No error message no nothing but still nothing happening...
I need the exact query which would work! :(
Details:
Table1: users column: id
Table2: Pokemon_ref column: pkmn_id
If an insertion is done in Table1 then it should also be added in Table2!
sample:
ALTER TABLE tablename
ADD CONSTRAINT FK_Name_ID FOREIGN KEY (fk_ID)
REFERENCES (R_id);
https://dev.mysql.com/doc/refman/5.1/en/create-table-foreign-keys.html
http://www.w3schools.com/sql/sql_foreignkey.asp
Alter table to give foreign key constraint
category INT NOT NULL, id INT NOT NULL,
price DECIMAL,
PRIMARY KEY(category, id)
) ENGINE=INNODB;
CREATE TABLE customer (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE product_order (
no INT NOT NULL AUTO_INCREMENT,
product_category INT NOT NULL,
product_id INT NOT NULL,
customer_id INT NOT NULL,
PRIMARY KEY(no),
INDEX (product_category, product_id),
INDEX (customer_id),
FOREIGN KEY (product_category, product_id)
REFERENCES product(category, id)
ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (customer_id)
REFERENCES customer(id)
)
I have the following schema. How do I ensure that all values in child are unique for a given child.group_id, child.type, and parent.status? Please note the 1-to-1 relationship between parent and child. If parent and child was one table, a simple UNIQUE index would work, however, I wish to keep the two tables separate. Ideally, stored procedures wouldn't be used, however, I am open to them if necessary. I am using the latest version of MySQL. Thank you
CREATE TABLE IF NOT EXISTS group (
id INT NOT NULL AUTO_INCREMENT ,
moreData VARCHAR(45) NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS parent (
id INT NOT NULL AUTO_INCREMENT ,
status VARCHAR(45) NOT NULL ,
moreData VARCHAR(45) NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS child (
parent_id INT NOT NULL ,
group_id INT NOT NULL ,
type INT NOT NULL ,
moreData VARCHAR(45) NULL ,
PRIMARY KEY (parent_id) ,
INDEX fk_child_group1_idx (group_id ASC) ,
CONSTRAINT fk_child_parent
FOREIGN KEY (parent_id )
REFERENCES parent (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_child_group1
FOREIGN KEY (group_id )
REFERENCES group (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
I think you're looking for something along these lines.
Create an overlapping constraint in "parent". (The column "id" is unique, so {id, any-other-column} must also be unique.)
CREATE TABLE IF NOT EXISTS parent (
id INT NOT NULL AUTO_INCREMENT ,
status VARCHAR(45) NOT NULL ,
moreData VARCHAR(45) NULL ,
PRIMARY KEY (id),
UNIQUE (id, status)
)
ENGINE = InnoDB;
Add the status column in "child".
CREATE TABLE IF NOT EXISTS child (
parent_id INT NOT NULL ,
parent_status VARCHAR(45) NOT NULL ,
group_id INT NOT NULL ,
type INT NOT NULL ,
moreData VARCHAR(45) NULL ,
Primary key constraint doesn't have to change.
PRIMARY KEY (parent_id) ,
INDEX fk_child_group1_idx (group_id ASC) ,
Reference the pair of columns.
CONSTRAINT fk_child_parent
FOREIGN KEY (parent_id, parent_status )
REFERENCES parent (id, status )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_child_group1
FOREIGN KEY (group_id )
REFERENCES group (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION) ,
Whether you ought to cascade updates in fk_child_parent is application-dependent. Give that some thought.
And add a unique constraint on the set of columns you say should be unique.
CONSTRAINT uq_child
UNIQUE (group_id, type, parent_status)
REFERENCES group (id))
ENGINE = InnoDB;
One option is to create before insert trigger to do this verification, check constraints are not supported by mysql so that's not an option.
I have the following tables:
CREATE TABLE `OBL2`.`item` (
`itemID` INT NOT NULL AUTO_INCREMENT ,
`itemName` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`itemID`) ,
INDEX `itemName` (`itemName` ASC) );
CREATE TABLE `OBL2`.`subject` (
`subjectID` INT NOT NULL ,
`subjectName` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`subjectID`) );
Now since the connection is many to many, each item can have many subject and each subject can be related to many items - I'd like to set a connection table.
This is my code:
CREATE TABLE `OBL2`.`itemsubjects` (
`itemID` INT NOT NULL ,
`subjectID` INT NOT NULL ,
PRIMARY KEY (`itemID`, `subjectID`) ,
INDEX `itemID_idx` (`itemID` ASC) ,
INDEX `subjectID_idx` (`subjectID` ASC) ,
CONSTRAINT `itemID`
FOREIGN KEY (`itemID` )
REFERENCES `OBL2`.`item` (`itemID` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `subjectID`
FOREIGN KEY (`subjectID` )
REFERENCES `OBL2`.`subject` (`subjectID` )
ON DELETE CASCADE
ON UPDATE CASCADE);
but for some reason the code of the 3rd table is not being accepted.
I get an error message:
ERROR 1005: Can't create table 'obl2.itemsubjects' (errno: 121)
I've read about the error on the internet and it says it's a known issue of MYSQL yet there are no solutions.
Any thoughts?
The MySQL docs say in FOREIGN KEY Constraints (emphasis mine):
If the CONSTRAINT symbol clause is given, the symbol value must be unique in the database. If the clause is not given, InnoDB creates the name automatically.
So, the reason that the itemsubject table creation failed, was that you had another (foreign key) constraint, named itemID, or one named subjectID in some other table of the database.
It's good to have a naming conevntion that is standard across the database. Just as you have ColumnName_idx for indices, you can use ReferencedTable_ReferencingTable_FK for foreign key constraints:
CREATE TABLE OBL2.itemsubjects (
itemID INT NOT NULL ,
subjectID INT NOT NULL ,
PRIMARY KEY
(itemID, subjectID) ,
INDEX itemID_idx -- I like these
(itemID ASC) ,
INDEX subjectID_idx -- two
(subjectID ASC) ,
CONSTRAINT item_itemsubject_FK -- what I propose, here
FOREIGN KEY (itemID)
REFERENCES OBL2.item (itemID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT subject_itemsubject_FK -- and here
FOREIGN KEY (subjectID)
REFERENCES OBL2.subject (subjectID)
ON DELETE CASCADE
ON UPDATE CASCADE
);