MySQL Using Same Foreign key for two different table columns - mysql

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.

Related

Error Code 1215 Cannot Add Foreign Code Constraint

My code:
CREATE TABLE Horse (
ID SMALLINT UNSIGNED AUTO_INCREMENT,
RegisteredName VARCHAR(15),
PRIMARY KEY (ID)
);
CREATE TABLE Student (
ID SMALLINT UNSIGNED AUTO_INCREMENT,
FirstName VARCHAR(20),
LastName VARCHAR(30),
PRIMARY KEY (ID)
);
CREATE TABLE LessonSchedule (
HorseID SMALLINT UNSIGNED NOT NULL,
StudentID SMALLINT UNSIGNED NOT NULL,
LessonDateTime DATETIME NOT NULL,
Primary Key (HorseID, StudentID, LessonDateTime),
Foreign Key (HorseID) REFERENCES Horse(ID)
ON DELETE CASCADE,
Foreign Key (StudentID) REFERENCES Student(ID)
ON DELETE SET NULL
);
I'm trying to create "LessonSchedule" with these requirements:
HorseID - integer with range 0 to 65 thousand, not NULL, partial primary key, foreign key references Horse(ID)
StudentID - integer with range 0 to 65 thousand, foreign key references Student(ID)
LessonDateTime - date/time, not NULL, partial primary key
If a row is deleted from Horse, the rows with the same horse ID should be deleted from LessonSchedule automatically.
If a row is deleted from Student, the same student IDs should be set to NULL in LessonSchedule automatically.
The create horse table and create student table was given to me.
I am getting the error:
Query failed: ERROR 1215 (HY000) at line 15:
Cannot add foreign key constraint
I tested your table creation statements, and then ran SHOW ENGINE INNODB STATUS. This includes a section that gives more specific information about the reason for the failure.
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2021-11-08 10:31:11 0x700002686000 Error in foreign key constraint of table test/lessonschedule:
Foreign Key (StudentID) REFERENCES Student(ID) ON DELETE SET NULL ):
You have defined a SET NULL condition though some of the
columns are defined as NOT NULL.
This means you can't define a foreign key with ON DELETE SET NULL if the column it is based on is defined with the NOT NULL option (as a PRIMARY KEY column must be).

Can you use data type: varchar() in MySQLl Databases?

I have tried adding a foreign key of type VARCHAR that references another table column with type VARCHAR as well. Both Columns are same type and length, but I keep getting an error: Failed to add the foreign key constraint. Missing index for constraint
The first table below has no problem when being created but the second table is the table to which throws the error: Failed to add the foreign key constraint. Missing index for constraint 'FK_Session_User' in the referenced table 'users'
The column I that I am trying to reference is the UserName Column.
CREATE TABLE Users (
UserID INT NOT NULL AUTO_INCREMENT,
Role_Code VARCHAR(15) NOT NULL,
UserName VARCHAR(40) NOT NULL,
Password TEXT NOT NULL,
CONSTRAINT PK_User PRIMARY KEY (UserID, UserName),
CONSTRAINT FK_User_Roles FOREIGN KEY (Role_Code)
REFERENCES Roles(Role_Code));
CREATE TABLE Auth_Users (
SessionID VARCHAR(96) NOT NULL,
UserName VARCHAR(40) NOT NULL,
Last_Visit TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT PK_AuthUser PRIMARY KEY (SessionID),
CONSTRAINT FK_Session_User FOREIGN KEY (UserName)
REFERENCES Users(UserName)
);
the problem is that UserName is not indexed indexed on Users. You should add an index to it. You can do it like this:
CREATE TABLE Users (
UserID INT NOT NULL AUTO_INCREMENT,
Role_Code VARCHAR(15) NOT NULL,
UserName VARCHAR(40) NOT NULL,
Password TEXT NOT NULL,
INDEX(UserName),
CONSTRAINT PK_User PRIMARY KEY (UserID, UserName),
CONSTRAINT FK_User_Roles FOREIGN KEY (Role_Code)
REFERENCES Roles(Role_Code)
);
UPDATE: With that said, please see this: https://stackoverflow.com/questions/588741/can-a-foreign-key-reference-a-non-unique-index#:~:text=From%20MySQL%20documentation%3A,unique%20columns%20of%20referenced%20table.
On why you shouldn't do that.
I would recommend normalizing you data in a way that you have only unique not nulls as your references.
In your case the simplest way to solve it would be to reference UserID in your foreign key. Also, that is what you most probably really want to do.

MySQL: Can't create table

I tried to create a table in MySQL using the CREATE TABLE statement below:
CREATE TABLE `visit` (
`visit_id` int(11) NOT NULL,
`site_id` int(11) DEFAULT NULL,
PRIMARY KEY (`visit_id`),
CONSTRAINT `FK_visit_site` FOREIGN KEY (`site_id`) REFERENCES `site` (`site_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I received this error:
ERROR 1005 (HY000): Can't create table 'fooschema.visit' (errno: 121)
I used SHOW ENGINE INNODB STATUS command. This is the error message:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
140222 7:03:17 Error in foreign key constraint creation for table `fooschema`.`visit`.
A foreign key constraint of name `fooschema/FK_visit_site`
already exists. (Note that internally InnoDB adds 'databasename/'
in front of the user-defined constraint name).
Note that InnoDB's FOREIGN KEY system tables store
constraint names as case-insensitive, with the
MySQL standard latin1_swedish_ci collation. If you
create tables or databases whose names differ only in
the character case, then collisions in constraint
names can occur. Workaround: name your constraints
explicitly with unique names.
Then, I used the query below to list all available constraints:
select *
from information_schema.table_constraints
where constraint_schema = 'fooschema'
I didn't see any constraint with name 'FK_visit_site' in the result.
The FK_visit_site constraint was a foreign key constraint of table visit. I dropped the visit table and attempted to recreate it.
Is there a way I can drop this foreign key constraint even when the table it was associated to doesn't exist?
your foreign key already exist , so either drop existed foreign key or rename your second key.
ALTER TABLE `site` DROP FOREIGN KEY `FK_visit_site`;
or rename to other new one.
CREATE TABLE `visit` (
`visit_id` int(11) NOT NULL PRIMARY KEY,
`site_id` int(11) NOT NULL,
CONSTRAINT `FK_visit_site` FOREIGN KEY (`site_id`) REFERENCES `site` (`site_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Added PRIMARY KEY to the visit_id line.
Note:
make sure that site_id in the site table have exact same datatype of site_id in visit table.
like that
`site_id` int(11) DEFAULT NULL --//in the `site` table
The two keys you're coupling must have the exact same datatype ( INT NOT NULL), even signedness
AFAIK, you will get this error when you're trying to add a constraint with a name that's already used somewhere else. Means, in your case FK FK_visit_site had already been used before.
If the table you're trying to create includes a foreign key constraint, and you've provided your own name for that constraint, remember that it must be unique within the database.
You can run the below query to find out the same
SELECT
constraint_name,
table_name
FROM
information_schema.table_constraints
WHERE
constraint_type = 'FOREIGN KEY'
AND table_schema = DATABASE()
ORDER BY
constraint_name;
Taken from the post here
http://www.thenoyes.com/littlenoise/?p=81
Try using a different name for your FK like
CREATE TABLE `visit` (
`visit_id` int(11) NOT NULL,
`site_id` int(11) DEFAULT NULL,
PRIMARY KEY (`visit_id`),
CONSTRAINT `FK_visit_site_New` FOREIGN KEY (`site_id`)
REFERENCES `site` (`site_id`),
)

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.

mysql error 150: cannot create table

I am stuck with this error no 150 problem in mysql and I know there have been questions
which discuss this problem but I still can't find where I am wrong. Here is the database I am trying to create:
create table business (
ident varchar(40) NOT NULL,
name varchar(50) NOT NULL,
rating INT UNSIGNED NOT NULL,
PRIMARY KEY(ident)
) ENGINE=InnoDB;
create table deals (
business_id varchar(40) NOT NULL,
deals_id varchar(20) NOT NULL,
deals_title varchar(50) NOT NULL,
PRIMARY KEY (business_id, deals_id),
FOREIGN KEY (business_id) REFERENCES business(ident) ON DELETE CASCADE
) ENGINE=InnoDB;
create table d_options (
business_id varchar(40) NOT NULL,
dealid varchar(20) NOT NULL,
option_title varchar(40) NOT NULL,
PRIMARY KEY(business_id, dealid, option_title),
FOREIGN KEY(business_id) REFERENCES business(ident) ON DELETE CASCADE,
FOREIGN KEY(dealid) REFERENCES deals(deals_id)
) ENGINE=InnoDB;
I get error: ERROR 1005 (HY000): Can't create table 'test.d_options' (errno: 150)
I know for foreign key constraints to be satisfied there should be a index in the parent table as per mysql documentation, but I think that there is by default indexing
on primary key.
The result of innodb status is:
120530 0:47:48 Error in foreign key constraint of table test/d_options:
FOREIGN KEY(dealid) REFERENCES deals(deals_id)
) ENGINE=InnoDB:
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.
Any help is appriciated.
You have a compound primary key on (business_id, deal_id) and they are indexed as a pair, but to satisfy the FK, you need another index on deal_id alone:
create table deals (
business_id varchar(40) NOT NULL,
deals_id varchar(20) NOT NULL,
deals_title varchar(50) NOT NULL,
PRIMARY KEY (business_id, deals_id),
FOREIGN KEY (business_id) REFERENCES business(ident) ON DELETE CASCADE,
/* Add an index on deals_id, separate from the compound PK */
INDEX idx_deals_id (deals_id)
) ENGINE=InnoDB;