How to Link Foreign Key with Different Name - mysql

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.

Related

How to create a table with a composite key made of 2 foreign keys referencing to other tables?

I have three tables A, B and funding:
Table A has a primary key partner_id
Table B has a primary key branch_id
When I try to create table C with the following code:
CREATE TABLE Funding (
partner_id INT,
branch_id INT,
total_fund FLOAT,
PRIMARY KEY (partners_id, branch_id),
FOREIGN KEY (partners_id) REFERENCES A(partner_id) ON delete SET NULL,
FOREIGN KEY (branch_id) REFERENCES B(branch_id) ON delete SET NULL
);
I get error message:
1830: column partner_id cannot be NOT NULL: needed in a foreign key constraint.
How can I solve this problem?
Create a separted ID for PK:
SQL DEMO
CREATE TABLE A (
partner_id INT,
PRIMARY KEY (partner_id)
);
CREATE TABLE B (
branch_id INT,
PRIMARY KEY (branch_id)
);
CREATE TABLE Funding (
id INT PRIMARY KEY AUTO_INCREMENT,
partner_id INT,
branch_id INT,
total_fund FLOAT,
FOREIGN KEY (partner_id) REFERENCES A(partner_id) ON DELETE SET NULL,
FOREIGN KEY (branch_id) REFERENCES B(branch_id) ON DELETE SET NULL
);
You can also add:
ALTER TABLE `Funding` ADD UNIQUE `unique_index`(partner_id, branch_id);
But that can cause problem when multiple partners from same branch are deleted
In CREATE TABLE Funding just add NOT NULL statement to partner_id and branch_id.
CREATE TABLE Funding ( partner_id INT NOT NULL, branch_id INT NOT NULL,...

#1005 - Can't create table 'xxx.item' (errno: 150)

I am creating Database for a Hotel and I am not able to create "Item" table.
The error shown is
#1005 - Can't create table 'xxx.item' (errno: 150)
Below are my SQL queries:
create table menu (
menu_id INT
, menu_name varchar(100)
, PRIMARY KEY (menu_id)
);
create table categories (
categories_id INT
, category_name varchar(100)
, PRIMARY KEY (categories_id)
);
create table menu_category_item (
mci_id INT
, menu_id INT
, categories_id INT
, item_id INT
, item_type INT
, restaurant_id INT
, PRIMARY KEY (mci_id)
, FOREIGN KEY (menu_id)
REFERENCES menu(menu_id)
, FOREIGN KEY (categories_id)
REFERENCES categories(categories_id)
, FOREIGN KEY (restaurant_id)
REFERENCES restaurants(restaurant_id)
);
create table item (
item_id INT
, item_name varchar(100)
, item_price decimal
, FOREIGN KEY (item_id)
REFERENCES menu_category_item (item_id)
);
Please help me out of this!!
I think the problem is in the structure of the database, you should have item_id as the primary key in the item table, then let the menu_category_item table reference that. Like:
create table item (
item_id INT
, item_name varchar(100)
, item_price decimal
, PRIMARY KEY (item_id));
create table menu_category_item (
mci_id INT
, menu_id INT
, categories_id INT
, item_id INT
, item_type INT
, restaurant_id INT
, PRIMARY KEY (mci_id)
, FOREIGN KEY (menu_id)
REFERENCES menu(menu_id)
, FOREIGN KEY (categories_id)
REFERENCES categories(categories_id)
, FOREIGN KEY (restaurant_id)
REFERENCES restaurants(restaurant_id)
, FOREIGN KEY (item_id)
REFERENCES item(item_id)
);
If I'm correct, your item table would contain the items, you would need a primary key there. And menu_item_category is basically matching items to menus, so there is where you add your foreign key.
Comment from #Adam below:
As a rule: 1 - every table should have a primary key and 2 - foreign
keys should usually be against the primary key the target table. There
are exceptions, but those rules are good starting places for basic DB
design IMO
Assuming that is all the SQL you're running, the problem here is that there's no restaurants table, so trying to create the menu_category_item gives error 150.
Since menu_category_item failed to create, then item can't reference it, so is also giving the 150 error.
This is detailed in the InnoDB error codes under ER_CANT_CREATE_TABLE.
I think you need a unique index/constraint on the target of a foriegn key (in this case menu_category_item.item_id so that it knows which row in the target table is referenced. But i may be getting my SQL flavours mixed up
menu_category_item.item_id has no index defined.
It is required to police the FOREIGN KEY constraint.
Added this - ALTER TABLE menu_category_item ADD INDEX menu_category_item (menu_category_item)
CREATE TABLE menu_category_item (
mci_id INT ,
menu_id INT,
categories_id INT ,
item_id INT ,
item_type INT,
restaurant_id INT ,
PRIMARY KEY (mci_id),
FOREIGN KEY (menu_id) REFERENCES menu(menu_id),
FOREIGN KEY (categories_id) REFERENCES categories(categories_id),
FOREIGN KEY (restaurant_id) REFERENCES restaurants(restaurant_id),
ALTER TABLE `menu_category_item` ADD INDEX `item_id` (`item_id`)
);

Foreign Key After Table Creation

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)
)

UNIQUE index spanning multiple tables

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.

Adding foreign key on multiple columns

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.