SQL table with multiple foriegn keys - mysql

I'm trying to make a table with multiple keys
CREATE TABLE Wishlist (ID integer NOT NULL, productname varchar(30) NOT NULL, price integer NOT NULL, email varchar(30) NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (productname) REFERENCES products (productname),
FOREIGN KEY (price) REFERENCES products (price),
FOREIGN KEY (email) REFERENCES products (email)
);
The error "a UNIQUE constraint does not exist on referenced columns repeats code" If i change it to:
CREATE TABLE Wishlist (ID integer UNIQUE NOT NULL, productname varchar(30) NOT NULL, price integer NOT NULL, email varchar(30) NOT NULL, // rest same as above
The error "a UNIQUE constraints already exists on the set of columns in statement repeats code" if i then remove the primary key, the first error message appears, any suggestions??

Foreign keys can only be configured on columns in the foreign table that are indexed. Make sure the columns in the foreign tables have an indexed configured. Typically, most foreign keys are configured to the tables PK but non-clustered index work also.

Related

MySQL Using Same Foreign key for two different table columns

I found this thread similar to my query:
How to Link Foreign Key with Different Name
But unfortunately the answer to the question above doesn't resolve my problem as on my example tables, it doesn't create any primary key, all foreign keys only.
Here is the query for the table structure:
CREATE TABLE ref_data(
user_id INT(11) NOT NULL,
ref_id INT(11) NOT NULL,
ref_name VARCHAR(30) NOT NULL,
ref_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT FK_user_id FOREIGN KEY(user_id) REFERENCES client (user_id),
CONSTRAINT FK_ref_id FOREIGN KEY(ref_id) REFERENCES client (user_id),
CONSTRAINT FK_ref_name FOREIGN KEY(ref_name) REFERENCES client (firstname)
);
I get the following error:
errno: 150 "Foreign key constraint is incorrectly formed"
Here I am using user_id twice, with the first as user_id and second as ref_id. I'm also using firstname as ref_name.
This is the client table:
CREATE TABLE client (
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(30) NOT NULL UNIQUE KEY,
`email` VARCHAR(50) NOT NULL UNIQUE KEY,
`firstname` VARCHAR(30) NOT NULL,
`lastname` VARCHAR(30) NOT NULL,
`password` CHAR(128) NOT NULL
);
Ok, when trying to create the ref_data table, after the foreign key error, I see this:
LATEST FOREIGN KEY ERROR
------------------------ 2017-07-13 01:07:00 37ec Error in foreign key constraint of table ref_data:
FOREIGN KEY(ref_name) REFERENCES client (firstname) ):
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.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition. Create table 'test.ref_data'
with foreign key constraint failed. There is no index in the
referenced table where the referenced columns appear as the first
columns near ' FOREIGN KEY(ref_name) REFERENCES client (firstname) )'.
What that error is basically saying: (in the bold text)
There is no index on 'firstname' for the 'client' table (the portion after the REFERENCES clause of the FOREIGN KEY
But it's a simple fix. Run this SQL on the client table:
ALTER TABLE `client` ADD INDEX(`firstname`);
... and then run the ref_data table SQL again.

mysql foreign key to compound primary key [duplicate]

This question already has answers here:
Composite key as foreign key (sql)
(2 answers)
Closed 6 years ago.
I try to achive the following using MySQL Server 5.x.
I have a table named Customer created like this:
CREATE TABLE Customer(
Title VARCHAR(30) NOT NULL,
Name VARCHAR(100) NOT NULL,
FirstName VARCHAR(100) NOT NULL,
Street VARCHAR(300) NOT NULL,
HouseNumber VARCHAR(30) NOT NULL,
ZipCode VARCHAR(30) NOT NULL,
City VARCHAR(100) NOT NULL,
Telephone VARCHAR(30) NOT NULL,
EMail VARCHAR(300) NULL,
CONSTRAINT PK_Customer PRIMARY KEY(Title,Name,FirstName),
INDEX Index_Name(Name));
And a second table Named 'Order' created like this:
CREATE TABLE `Order`(
Number BIGINT NOT NULL AUTO_INCREMENT,
Customer VARCHAR(230) NOT NULL,
Issued DATETIME NOT NULL,
PRIMARY KEY(Number),
CONSTRAINT FK_Customer FOREIGN KEY(Customer)
REFERENCES Customer(PK_Customer));
But I get an error with the number:
ERROR 1005 (HY000): Can't create table 'SBZ.Order' (errno: 150)
The innodb engine status shows me this:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
160317 16:05:29 Error in foreign key constraint of table SBZ/Order:
FOREIGN KEY(Customer) REFERENCES Customer(PK_Customer)):
Cannot resolve column name close to:
))
Is it possible to create a foreign key to a compound primary key using constraint?
Any help appriciated. :)
First, you should have a CustomerId column in the first table. It should be auto-incremented. So the right definitions are:
CREATE TABLE Customer (
CustomerId int auto_increment primary key,
. . .
unique (title, firstname, name)
);
Then you can create a correct foreign key relationship to CustomerId:
CustomerId int,
. . .
CONSTRAINT FK_Customer FOREIGN KEY(CustomerId) REFERENCES Customer(CustomerId)
This is "right" because such synthetic keys have several advantages:
Foreign key references are much simpler.
You can change the components easily (changing part of a foreign key requires understanding cascading constraints).
Integers in indexes are more efficient than strings.
Of course, you can do the same with a composite primary key. You just need all three columns in the second table:
Title VARCHAR(30),
Name VARCHAR(100),
FirstName VARCHAR(100),
CONSTRAINT FK_Customer FOREIGN KEY(Title, Name, Firstname) REFERENCES Customer(Title, Name, Firstname)
Your child table's foreign key must contain the same columns, in the same order, as the primary key of the parent table. In your case it would look like
CREATE TABLE `Order`(
Number BIGINT NOT NULL AUTO_INCREMENT,
Title VARCHAR(30) NOT NULL,
Name VARCHAR(100) NOT NULL,
FirstName VARCHAR(100) NOT NULL,
...
CONSTRAINT FK_Customer FOREIGN KEY (Title, Name, FirstName)
REFERENCES Customer (Title, Name, FirstName)
);
Note the columns don't have to be in the same order in the table, just in the constraint's column list.

MySQL : Error Code 1215 : Cannot add foreign key constraint

I'm trying to make a simple SQL schema, but I'm having some problem with defining foreign keys. I really don't have that much MySQL knowledge, so I thought I'd ask her for some help. I get Error Code 1215 when I try to create the foreign key roomID and 'guestEmail' in the HotelManagement.Reservation table creation.
CREATE database HotelManagement;
CREATE TABLE HotelManagement.Room (
roomID INT not null auto_increment,
roomTaken TINYINT(1),
beds INT not null,
size INT not null,
roomRank INT not null,
PRIMARY KEY(roomID));
CREATE TABLE HotelManagement.HotelTask (
taskType INT not null,
taskStatus TINYINT(1) not null,
whichRoom INT not null,
note VARCHAR(255),
PRIMARY KEY (taskType),
FOREIGN KEY (whichRoom) REFERENCES HotelManagement.Room(roomID));
CREATE TABLE HotelManagement.Guest (
firstName varchar(25) not null,
lastName varchar(25) not null,
userPassword varchar(25) not null,
email varchar(25) not null,
reservation INT,
PRIMARY KEY (userPassword, email));
CREATE TABLE HotelManagement.Reservation (
reservationID INT not null,
id_room INT not null,
guestEmail varchar(25) not null,
fromDate DATE not null,
toDate DATE not null,
PRIMARY KEY (reservationID),
FOREIGN KEY (guestEmail)
REFERENCES HotelManagement.Guest(email),
FOREIGN KEY (id_room)
REFERENCES HotelManagement.Room(roomID)
);
ALTER TABLE HotelManagement.Guest
ADD CONSTRAINT res_constr FOREIGN KEY (reservation)
REFERENCES HotelManagement.Reservation(reservationID);
Updated the .sql
In the hoteltask table you have already defined a foreign key named roomid. Foreign key names also have to be unique, so just give a different name to the 2nd foreign key or omit the name completely:
If the CONSTRAINT symbol clause is given, the symbol value, if used,
must be unique in the database. A duplicate symbol will result in an
error similar to: ERROR 1022 (2300): Can't write; duplicate key in
table '#sql- 464_1'. If the clause is not given, or a symbol is not
included following the CONSTRAINT keyword, a name for the constraint
is created automatically.
UPDATE
The email field in the guest table is the rightmost column of the primary key, this way the pk cannot be used to independently look up email in that table. Either change the order or fields in the pk, or have a separate index on email field in the guest table. Quote from the same link as above:
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
Pls read through the entire documentation I linked before proceeding with creating the fks!
Side note 2 (1st is in the comments below): you should probably have a unique numeric guest id because that is lot more efficient than using email. Even if you decide to stick with email as id, I would restrict the pk in the guest table to email only. With the current pk I can register with the same email multiple times if I use different password.

MySQL error for 2 tables cannot add foreign key constraint

I am trying to create 2 tables in the same database. however it still cannot create foreign key.
create table countryadrc
(
adrc char(3) not null,
county varchar(30) not null,
primary key (adrc),
unique (adrc, county)
);
it is the other table which observe the error
create table localities
(
county varchar(30) not null,
locality tinyint not null,
primary key (county),
foreign key (county) references countryadrc (county)
);
Your schema seems to be a little strange but you can technically make it work if you swap columns in UNIQUE constraint in countryadrc table.
Using FOREIGN KEY Constraints
... In the referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order ...
create table countryadrc
(
adrc char(3) not null,
county varchar(30) not null,
primary key (adrc),
unique (county, adrc) -- county should be the leftmost column in the index
);
Here is SQLFiddle demo

MySQL error 1215 Cannot add Foreign key constraint - FK in different tables

im new on mysql workbench, and i tried so many things to put my script working but i simply cant... Ive got these tables:
CREATE TABLE Utilizador (email varchar(40) not null, nome varchar(50)
not null, dataNascimento date, profissao varchar(50) not null,
reputacao double(3,2) unsigned not null, constraint pk_Utilizador
primary key(email))
This is the first table created!
CREATE TABLE POI (email varchar(40) not null, designacaoPOI
varchar(10) not null, coordenadaX int, coordenadaY int,
descricaoPOI varchar(200), constraint pk_POI primary key(email,
designacaoPOI), constraint fk_POI foreign key(email) references
Utilizador(email) on delete cascade)
This is the second table created!
CREATE TABLE Utilizador_POI (email varchar(40) not null, designacaoPOI
varchar(10) not null, constraint pk_Utilizador_POI primary key(email,
designacaoPOI), constraint fk1_Utilizador_POI foreign key(email)
references Utilizador(email) on delete cascade, constraint
fk2_Utilizador_POI foreign key(designacaoPOI) references
POI(designacaoPOI) on delete cascade)
This table gives me the error: Error Code: 1215. Cannot add foreign key constraint
I did some tests and im almost sure that the problem is in the foreign key "designacaoPOI". The other FK ("email") dont give me any error, so maybe the problem is in the Table POI?
Thanks in advanced!
The problem here is twofold:
1/ Use IDs for PRIMARY KEYs
You should be using IDs for primary keys rather than VARCHARs or anything that has any real-world "business meaning". If you want the email to be unique within the Utilizador table, the combination of email and designacaoPOI to be unique in the POI table, and the same combination (email and designacaoPOI) to be unique in Utilizador_POI, you should be using UNIQUE KEY constraints rather than PRIMARY KEY constraints.
2/ You cannot DELETE CASCADE on a FOREIGN KEY that doesn't reference the PRIMARY KEY
In your third table, Utilizador_POI, you have two FOREIGN KEYs references POI. Unfortunately, the PRIMARY KEY on POI is a composite key, so MySQL has no idea how to handle a DELETE CASCADE, as there is not a one-to-one relationship between the FOREIGN KEY in Utilizador_POI and the PRIMARY KEY of POI.
If you change your tables to all have a PRIMARY KEY of ID, as follows:
CREATE TABLE blah (
id INT(9) AUTO_INCREMENT NOT NULL
....
PRIMARY KEY (id)
);
Then you can reference each table by ID, and both your FOREIGN KEYs and DELETE CASCADEs will work.
I think the problem is that Utilizador_POI.email references POI.email, which itself references Utilizador.email. MySQL is probably upset at the double-linking.
Also, since there seems to be a many-to-many relationship between Utilizador and POI, I think the structure of Utilizador_POI isn't what you really want. Instead, Utilizador_POI should reference a primary key from Utilizador, and a matching primary key from POI.
The problem is in your second table. Your primary key is (email,designacaoPOI), when you try to reference that in your table it gives you error because of this:
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
For it to work, either change the order of your second tale PRIMARY KEY :
CREATE TABLE POI (
email VARCHAR(40) NOT NULL,
designacaoPOI VARCHAR(10) NOT NULL,
coordenadaX INT,
coordenadaY INT,
descricaoPOI VARCHAR(200),
CONSTRAINT pk_POI PRIMARY KEY (designacaoPOI,email), -- changed the order
CONSTRAINT fk_POI FOREIGN KEY (email)
REFERENCES Utilizador(email) ON DELETE CASCADE
);
sqlfiddle demo
or add an index for designacaoPOI:
CREATE TABLE POI (
email VARCHAR(40) NOT NULL,
designacaoPOI VARCHAR(10) NOT NULL,
coordenadaX INT,
coordenadaY INT,
descricaoPOI VARCHAR(200),
CONSTRAINT pk_POI PRIMARY KEY (designacaoPOI,email),
KEY key_designacaoPOI(designacaoPOI), -- added index for that column
CONSTRAINT fk_POI FOREIGN KEY (email)
REFERENCES Utilizador(email) ON DELETE CASCADE
);
sqlfiddle demo
Either of these solutions will let you create your third table without errors.