Add Foreign Key to existing table (error 1451) - mysql

I have two tables, with foreign keys, but when delete a record from 'fb_campaign' get follow error:
#1451 - Cannot delete or update a parent row: a foreign key constraint fails (mydb.fb_campaign_cat, CONSTRAINT fb_campaign_cat_ibfk_1 FOREIGN KEY (id) REFERENCES fb_campaign (id_cat))
Issue occurs when I add the second foreign key.
table1: fb_campaign_cat
+----+-----------+
| id | fb_cat |
+----+-----------+
| 1 | category1 |
| 2 | category2 |
| 3 | category3 |
+----+-----------+
table2: fb_campaign
+-------+--------+-----------+
| id_fb | id_cat | name |
+-------+--------+-----------+
| 1 | 1 | campaign1 |
| 2 | 2 | campaign2 |
+-------+--------+-----------+
** schema **
CREATE TABLE `fb_campaign_cat` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fb_cat` varchar(30) CHARACTER SET utf8mb4 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `fb_campaign` (
`id_fb` int(11) NOT NULL AUTO_INCREMENT,
`id_cat` int(11) NOT NULL,
`name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
FOREIGN KEY
ALTER TABLE fb_campaign
ADD CONSTRAINT fb_campaign_cat
FOREIGN KEY (id_cat)
REFERENCES fb_campaign_cat(id)
ON DELETE CASCADE;
ALTER TABLE fb_campaign_cat
ADD FOREIGN KEY (id) REFERENCES fb_campaign(id_cat);

The simple way would be to disable the foreign key check; make the changes then re-enable foreign key check.
SET FOREIGN_KEY_CHECKS=0; -- to disable them
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them

Related

Keep getting foreign key constraint failed message in My SQL

I tried to insert data into the table Bookratings, but I keep getting this error message. Is this because when I try to insert, it creates duplicates in the Bookratings table, which is not allowed by the PRIMARY key constraint?
MySQL Error 1452 - Cannot add or update a child row: a foreign key constraint fails
My actual code:
drop database if exists amazon2;
create database if not exists amazon2;
use amazon2;
create table books(
ISBN varchar(13),
Title varchar(255),
Author varchar(255),
Year int(10),
Puplisher varchar(255),
ImageURL varchar(255),
Genre varchar(12),
unitprice decimal(6,2),
primary key (ISBN)
);
create table users(
UserID int(11),
Country varchar(250),
Age int(11),
primary key (UserID)
);
create table bookratings(
UserID int(11) not null,
ISBN varchar(13) not null,
Rating int(11),
primary key (UserID, ISBN),
foreign key (ISBN) references books (ISBN) on delete cascade on update cascade,
foreign key (UserID) references users (UserID) on delete cascade on update cascade
);
create table orders(
OrderID int(11),
UserID int(11) not null,
Year int(10),
totalpay decimal(6,2),
primary key (OrderID),
foreign key (UserID) references users (UserID)
);
create table trans(
OrderID int(11) not null,
ISBN varchar(13) not null,
Quantity int(11),
primary key (OrderID, ISBN),
foreign key (OrderID) references orders (OrderID),
foreign key (ISBN) references books (ISBN)
);
I have to clarify something: Given by the task, I am not allowed to add any other attributes or delete the existing attributes.
Foreign key constraint violation means the table you're trying to update contains references to some other table, and you're somehow breaking that reference.
If I've got a table Movies
+----------+---------------+
| Movie_ID | Movie_Name |
+----------+---------------+
| 1 | Jaws |
| 2 | Star-Wars |
| 3 | Jurassic Park |
+----------+---------------+
And a table User_Reviews
+---------+----------+-------+
| User_ID | Movie_ID | Score |
+---------+----------+-------+
| 1 | 1 | 2.5 |
| 2 | 1 | 5 |
| 3 | 2 | 4 |
| 4 | 2 | 3 |
| 5 | 2 | 4.5 |
| 6 | 3 | 5 |
+---------+----------+-------+
In the User_Reviews table, Movie_ID is a foreign key.
I can't have a review with Movie_ID = 10, because that movie doesn't exist in the Movies table. If I did try to do that, I'd get a foreign key constraint error.

Fulltext working on MySQL 5.6, not 5.7

I have 2 main tables (professional_account & professional_profile) and 3 sub tables (prof_knows_about, prof_keywords & prof_recent_jobs) which are 1:many off professional_profile.
A FT search should match the search term in professional_profile.professional_statement, OR any row (for that professional_id) of prof_knows_about.knowledge_desc, OR any row of prof_keywords.keyword OR any row of prof_recent_jobs.job_title
In a 5.6.35 server it works as expected, but in 5.7.10 I only get results if the search term is in professional_profile.professional_statement or prof_knows_about.knowledge_desc - the search term is not found in the other two tables. Both servers run on freeBSD UNIX.
I tried both servers with the query pasted into the shell. Both also give same EXPLAIN output. Used a dump from the 5.7 on the 5.6 to ensure same data and table creates.
I did a show variables on both servers, but hard to compare as there are many extra values in the 5.7. Set both to same sql_mode.
Tables, query and explain listed below.
Is this an issue with my query, or my 5.7 server?
select email, PROFILE.*
FROM professional_account as ACC
join professional_profile as PROFILE on ACC.professional_id=PROFILE.professional_id
join prof_knows_about as KNOWS on PROFILE.professional_id=KNOWS.professional_id
join prof_keywords as KEYW on PROFILE.professional_id = KEYW.professional_id
join prof_recent_jobs as ROLES on PROFILE.professional_id=ROLES.professional_id
where status in ('LIVE','EDITS')
and (
match (knowledge_desc) against ('ramble')
or match (job_title) against ('ramble')
or match (keyword) against ('ramble')
or match (professional_statement) against ('ramble')
)
group by PROFILE.professional_profile_id
+----+-------------+---------+------------+--------+--------------------------------+-----------------+---------+---------------------------+------+----------+---------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+--------+--------------------------------+-----------------+---------+---------------------------+------+----------+---------------------------------+
| 1 | SIMPLE | KNOWS | NULL | ALL | professional_id | NULL | NULL | NULL | 43 | 100.00 | Using temporary; Using filesort |
| 1 | SIMPLE | PROFILE | NULL | ref | PRIMARY,professional_statement | professional_id | 4 | xxx.KNOWS.professional_id | 1 | 28.57 | Using where |
| 1 | SIMPLE | ACC | NULL | eq_ref | PRIMARY | PRIMARY | 4 | xxx.KNOWS.professional_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | ROLES | NULL | ref | professional_id | professional_id | 4 | xxx.KNOWS.professional_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | KEYW | NULL | ref | professional_id | professional_id | 4 | xxx.KNOWS.professional_id | 2 | 100.00 | Using where |
+----+-------------+---------+------------+--------+--------------------------------+-----------------+---------+---------------------------+------+----------+---------------------------------+
CREATE TABLE professional_account (
professional_id int(11) NOT NULL AUTO_INCREMENT,
email varchar(60) NOT NULL,
PRIMARY KEY (professional_id),
KEY email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE professional_profile (
professional_profile_id int(11) NOT NULL AUTO_INCREMENT,
professional_id int(11) NOT NULL,
status enum('BLANK','PART_WAIT','PART_APP','COMP_WAIT','COMP_APP','LIVE','EDITS') DEFAULT NULL,
professional_statement text,
PRIMARY KEY (professional_profile_id),
KEY professional_id (professional_id),
FULLTEXT KEY professional_statement (professional_statement),
CONSTRAINT fk_professional_profile_professional_account FOREIGN KEY (professional_id) REFERENCES professional_account (professional_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE prof_knows_about (
prof_knows_about_id int(11) NOT NULL AUTO_INCREMENT,
professional_id int(11) NOT NULL,
knowledge_desc varchar(100) DEFAULT NULL,
PRIMARY KEY (prof_knows_about_id),
KEY professional_id (professional_id),
FULLTEXT KEY knowledge_desc (knowledge_desc),
CONSTRAINT fk_prof_knows_about_professional_profile1 FOREIGN KEY (professional_id) REFERENCES professional_profile (professional_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE prof_keywords (
prof_keywords_id int(11) NOT NULL AUTO_INCREMENT,
professional_id int(11) NOT NULL,
keyword varchar(20) DEFAULT NULL,
PRIMARY KEY (prof_keywords_id),
KEY professional_id (professional_id),
FULLTEXT KEY keyword (keyword),
CONSTRAINT fk_prof_keywords_professional_profile1 FOREIGN KEY (professional_id) REFERENCES professional_profile (professional_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE prof_recent_jobs (
prof_recent_jobs_id int(11) NOT NULL AUTO_INCREMENT,
professional_id int(11) NOT NULL,
job_title varchar(100) DEFAULT NULL,
experience tinyint(2) DEFAULT NULL,
PRIMARY KEY (prof_recent_jobs_id),
KEY professional_id (professional_id),
FULLTEXT KEY job_title (job_title),
CONSTRAINT fk_prof_recent_jobs_professional_profile1 FOREIGN KEY (professional_id) REFERENCES professional_profile (professional_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE prof_keywords (
prof_keywords_id int(11) NOT NULL AUTO_INCREMENT,
professional_id int(11) NOT NULL,
keyword varchar(20) DEFAULT NULL,
PRIMARY KEY (prof_keywords_id),
KEY professional_id (professional_id),
FULLTEXT KEY keyword (keyword),
CONSTRAINT fk_prof_keywords_professional_profile1 FOREIGN KEY (professional_id) REFERENCES professional_profile (professional_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

How to set a foreign key to point to an autoincrement int?

I am trying to set up a MySQL database where a column is a foreign key pointing to another table that auto increments. When I try to create the table with the foreign key, I get the following error:
Can't create table '{DATABASE}' . '{TABLE}' (errorno: 150 "Foreign key constraint is incorrectly formed")
An answer found here says that the problem could be that I am trying to set a normal int as a foreign key pointing to an autoincrement int. How should I go about setting up my table structure?
Here is the statement that produces the error:
create table test_scores(id INT NOT NULL AUTO_INCREMENT,
student_id INT,
FOREIGN KEY (id) REFERENCES students(student_id) ON DELETE CASCADE,
test_id INT NOT NULL,
FOREIGN KEY (test_id) REFERENCES tests(id) ON DELETE CASCADE,
score INT NOT NULL,
PRIMARY KEY (id));
Parent tables:
students
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
tests
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
On this line:
FOREIGN KEY (id) REFERENCES students(student_id) ON DELETE CASCADE,
you probably meant to do this:
FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,
Otherwise you're trying to make id the foreign key, which isn't going to work because you can't know what id is even going to be until you insert a record. Additionally, students has no student_id column, so the attempt to use it as the relationship for the foreign key would fail.

MYSQL can't add a foreign key

I really can't get a clue, as everything seems to be ok. This is the command I'm trying:
ALTER TABLE dashboard ADD CONSTRAINT FOREIGN KEY (app_name, app_parent, client)
REFERENCES apps(app_name, app_parent, client) ON DELETE CASCADE ON UPDATE CASCADE;
This is the error I get:
ERROR 1215 (HY000): Cannot add foreign key constraint
Using an explicit name for the FK doesn't help. This is the referenced table:
mysql> SHOW COLUMNS IN apps;
+------------+------------------+------+-----+------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+------------+-------+
| app_name | varchar(20) | NO | PRI | | |
| app_parent | varchar(20) | NO | PRI | | |
| client | varchar(12) | NO | PRI | NULL | |
| order_idx | int(10) unsigned | YES | | 100 | |
...
And this is the referencing table:
mysql> SHOW COLUMNS IN dashboard;
+------------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------------------+------+-----+---------+-------+
| app_name | varchar(20) | NO | | | |
| app_parent | varchar(20) | NO | | | |
| client | varchar(12) | NO | | NULL | |
| widget | varchar(20) | YES | | NULL | |
...
Both tables have InnoDB as the engine. And this is the (rather laconic) clue I'm getting from SHOW ENGINE InnoDB STATUS:
LATEST FOREIGN KEY ERROR
------------------------
2014-06-20 11:49:57 10ec Error in foreign key constraint of table the_db/#sql-128c_2:
FOREIGN KEY (app_name, app_parent, client)
REFERENCES apps(app_name, app_parent, client) ON DELETE CASCADE ON UPDATE CASCADE:
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.
What does it mean it doesn't find an index on apps? I'm referencing primary keys! And the types are clearly the same.
EDIT: this is the CREATE command for apps:
CREATE TABLE `apps` (
`app_name` varchar(20) NOT NULL DEFAULT '',
`app_parent` varchar(20) NOT NULL DEFAULT '',
`client` varchar(12) NOT NULL,
`order_idx` int(10) unsigned DEFAULT '100',
...,
PRIMARY KEY (`app_name`,`app_parent`,`client`),
KEY `client` (`client`),
CONSTRAINT `apps_ibfk_1` FOREIGN KEY (`client`) REFERENCES `clients` (`name`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `apps_ibfk_2` FOREIGN KEY (`app_name`, `app_parent`) REFERENCES `app_list` (`name`, `parent`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
I must add that I actually managed to create a foreign key on the same columns on another table:
mysql> SHOW COLUMNS IN user_apps;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| app_name | varchar(20) | NO | PRI | | |
| app_parent | varchar(20) | NO | PRI | | |
| username | varchar(20) | NO | PRI | | |
| client | varchar(12) | YES | | NULL | |
...
Here, app_name, app_parent and client reference to the same named columns in apps.
This is probably the sneakiest of the mistakes: the problem was the default character set, which is latin1 for apps and utf8 for dashboard.
This solved my problem:
ALTER TABLE dashboard CONVERT TO CHARACTER SET latin1;
You better have posted output of
show create table apps
I am not sure if the referenced parent columns are indexed.
But for them to be eligible for referring from other child tables, they MUST have INDEXed
As per documentation on foreign key constraints:
REFERENCES tbl_name (index_col_name,...)
Define an INDEXes on columns app_name, app_parent, client of apps table.
If not already defined, then use following command:
ALTER TABLE apps
ADD INDEX ix_app_name( app_name )
, ADD INDEX ix_app_parent( app_parent )
, ADD INDEX ix_app_client( client )
And other primary constraints are that,
The child column definition MUST match with that of parent column.
Database ENGINE type must be same.
Refer to:
MySQL ALTER TABLE Syntax
MySQL Using FOREIGN KEY Constraints
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION

Unable to create Foreign Key (ERROR 1072)

I have a table which looks like this:
mysql> SHOW COLUMNS FROM Users;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| user_id | int(10) | NO | PRI | NULL | auto_increment |
| username | varchar(50) | YES | | NULL | |
| password | varchar(255) | YES | | NULL | |
| email | varchar(255) | YES | | NULL | |
| phone | varchar(255) | YES | | NULL | |
I am trying to create a new table like this:
create table jobs (id int, FOREIGN KEY (user_id) REFERENCES Users(user_id)) ENGINE=INNODB;
But I am getting this error:
ERROR 1072 (42000): Key column 'user_id' doesn't exist in table
I am sure I am missing something very basic.
Try this:
create table jobs (
id int,
user_id int,
FOREIGN KEY (user_id) REFERENCES Users(user_id)
) ENGINE=INNODB;
The first user_id in foreign key constraint refers to the table where the contraint is defined and the second refers to the table where it is pointing to.
So you need a field user_id in your jobs table, too.
This is the script you need:
CREATE TABLE jobs
(
id int NOT NULL,
user_id int NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES Users(user_id)
)
Here's a good reference to learn the basics about setting up relationships: SQL FOREIGN KEY Constraint
You're trying to define as FOREIGN KEY, a column which is not present on your query.
That's the reason why you are receiving Key column 'user_id' doesn't exist in table
Observe your query:
create table jobs (
id int,
FOREIGN KEY (user_id) REFERENCES Users(user_id)
) ENGINE=INNODB;
As the other answers have demonstrated:
you have to define the creation of the column of your new table, which will be a FK for a PK from another table
create table jobs (
id int,
user_id int NOT NULL
FOREIGN KEY (user_id) REFERENCES Users(user_id)
) ENGINE=INNODB;
Create table attendance:
CREATE TABLE tbl_attendance
(
attendence_id INT(100) NOT NULL,
presence varchar(100) NOT NULL,
reason_id varchar(100) NULL,
PRIMARY KEY (attendance_id)
);