I have a question regarding Foreign Keys in an InnoDB Table. I have 4 tables in my database:
Signup:
UID - Primary Key
Afid
Planid
Industryid
Affiliates:
Afid - Primary Key
Plans:
Planid - Primary Key
Industries:
Industryid - Primary Key
SQL I use to add the keys:
CONSTRAINT `FK_signup_industries` FOREIGN KEY (`industryid`) REFERENCES `industries` (`industryid`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_signup_affiliates` FOREIGN KEY (`afid`) REFERENCES `affiliates` (`afid`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_signup_plans` FOREIGN KEY (`planid`) REFERENCES `plans` (`planid`) ON UPDATE CASCADE ON DELETE CASCADE
What my question is:
If I was to delete a plan or an industry on their respective tables would the user in the signup table be deleted? I have tried to find guides on this and they don't explain it very well.
Basically what I need done is that the row in the signup table never to be deleted no matter what. When I use this query:
CONSTRAINT `FK_signup_plans` FOREIGN KEY (`planid`) REFERENCES `plans` (`planid`) ON UPDATE CASCADE ON DELETE NO ACTION
I get this error:
Cannot delete a parent row.
If you need the row in Signup to stay even if you delete the referenced row in Industries, Affiliates, or Plans, then you have two choices:
Do not declare a foreign key constraint. This removes enforcement of referential integrity, but it allows rows to exist in Signup that reference a parent primary key value that no longer exists.
Use ON DELETE SET NULL. This allows the row to stay, but the foreign key value that references the now-deleted parent will be changed.*
For more details see http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
* The standard SQL specification also defines a rule ON DELETE SET DEFAULT, but InnoDB doesn't support this feature.
Related
I'm using MySQL 5.6 and I've read the MySql Reference guide regarding this but no where is it mentioned that the PK should be at the end of the list while creating a composite Foreign Key.
The only requirement in the guide that talks about columns is the following -
"In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order."
If so, then why doesn't the following work?
alter table table_1
add constraint "fk_key_1" FOREIGN KEY "ix_key_1" ("col_1", "col_2") REFERENCES "table_2" ("pk_col", "col_2") ON DELETE NO ACTION;
But this works -
alter table table_1
add constraint "fk_key_1" FOREIGN KEY "ix_key_1" ("col_1", "col_2") REFERENCES "table_2" ("col_2", "pk_col") ON DELETE NO ACTION;
The foreign key has to match the primary key (or some key, but preferably the primary one) -- both the types and order.
If this works:
FOREIGN KEY "ix_key_1" ("col_1", "col_2") REFERENCES "table_2 ("col_2", "id_col") ON DELETE NO ACTION;
It is because the primary key on table_2 is defined as (col_2, id_col) rather than (id_col, col_2).
I am trying to add foreign key 'USERNAME' in tutorial table, but there was an error.
Executing:
ALTER TABLE `databse`.`tutorial`
ADD CONSTRAINT `USERNAME`
FOREIGN KEY (`USERNAME`)
REFERENCES `databse`.`register` (`USERNAME`)
ON DELETE CASCADE
ON UPDATE CASCADE;
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1452: Cannot add or update a child row:
a foreign key constraint fails (`databse`.`#sql-e7c_5`, CONSTRAINT `USERNAME` FOREIGN KEY (`USERNAME`)
REFERENCES `register` (`USERNAME`) ON DELETE CASCADE ON UPDATE CASCADE)
SQL Statement:
ALTER TABLE `databse`.`tutorial`
ADD CONSTRAINT `USERNAME`
FOREIGN KEY (`USERNAME`)
REFERENCES `databse`.`register` (`USERNAME`)
ON DELETE CASCADE
ON UPDATE CASCADE
Foreign key setting:
Tutorial table setting:
Any ideas ? thank you
I solved it, i created a new 'tutorials' table replace 'tutorial' table, and use same way to add foreign key, it worked! = =
still thank you for your helps !!
as stated here :
A FOREIGN KEY is a field (or collection of fields) in one table that refers to the PRIMARY KEY in another table.
In the code you show : you try to reference the "USERNAME" column, wich is not a primary key in your last capture
So you can either change your primary key in the register table to USERNAME, or you can change the foreign key to reference TutorialName
You have two table one is child table and second is parent table .So you would need to guarantee that each child column has NULL or has values that present in parent column.
This problem is normally caused by mismatching of values presented in the two columns constrained by the new foreign key.
That is, the value presented in the child table does not have a reference presented in the parent table.
when creating a foreign key, you need to make sure that:
the table type supports foreign key
there is a index on the foreign key column
the types of data of the two columns constrained by a foreign key are similar enough so that they can be converted to each other
the data presented in both columns constrained by a foreign key is consistent.
I have a table user with userID as the primary key. I have another table called Friends. In the Friends table, I have two Users as friends represented by the columns UserID and FrndID where both UserID and FrndID should be a userID in table user.
I want to enforce data integrity. Could I use something like this?
ADD CONSTRAINT `ufd_users_fk` FOREIGN KEY (`userId`, `friendId`)
REFERENCES `users` (`userId`, `userId`) ON DELETE CASCADE ON UPDATE CASCADE;
I want to know is REFERENCESusers(userId,userId) referencing a column multiple times correctly? The reason I am not creating 2 separate constraints, is that both users must exist in table user.
No, you should create two foreign keys:
ADD CONSTRAINT `ufd_users_fk` FOREIGN KEY (`userId`)
REFERENCES `users` (`userId`)
ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `ufd_users_fk` FOREIGN KEY (`friendId`)
REFERENCES `users` (`userId`)
ON DELETE CASCADE ON UPDATE CASCADE;
SETTING
I have a rails application that references an external mysql server. I am about to push some changes to the rails application. I made some changes to my local/test version of the application's database using rails migrations, but my production/live version of the application's database is not on a server that has the rails application, so I don't think I can just run the rails migration on the mysql database.
QUESTION
How do I safely add the following column, key and constraint:
`item_id` int(11) DEFAULT NULL,
KEY `index_notifications_on_item_id` (`item_id`),
CONSTRAINT `fk_rails_f395ae520f` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`) ON DELETE CASCADE,
and safely change the unique key:
UNIQUE KEY `item_id_and_user_id_stand_id_unique_index` (`item_id`,`user_id`,`stand_id`)
to
UNIQUE KEY `item_id_and_user_id_stand_id_notified_user_id_unique_index` (`item_id`,`user_id`,`stand_id`,`notified_user_id`),`)
ATTEMPTS
CONCERNING THE CONSTRAINT AND KEY
I try running:
ALTER TABLE notifications ADD FOREIGN KEY fk_rails_f395ae520f(item_id) REFERENCES items(id) ON DELETE CASCADE;
But, I run into 2 issues:
1: It names the key what I want the constraint to be named and makes up its own constraint name.
OUTPUT:
KEY `fk_rails_f395ae520f` (`item_id`),
CONSTRAINT `notifications_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`) ON DELETE CASCADE,
It requires me to temporarily set: set foreign_key_checks = 0; or else I get the error:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (DB_NAME.#sql-3c9_49, CONSTRAINT #sql-3c9_49_ibfk_2 FOREIGN KEY (item_id) REFERENCES items (id) ON DELETE CASCADE)
and I do not know if doing that is "safe" to do on a production/live server.
CONCERNING THE COLUMN AND UNIQE KEY
I believe I have the column and unique keys safely added with:
ALTER TABLE notifications add COLUMN item_id INT(11) DEFAULT NULL;
ALTER TABLE notifications DROP INDEX index_notifications_on_user_id_and_notified_user_id, ADD UNIQUE KEY `item_id_and_user_id_stand_id_notified_user_id_unique_index` (stand_id, user_id, notified_user_id, item_id);
CLARIFICATION
The reason I bring up the column and unique key even though I may have it working is the same reason I gave a setting: I am new to this and may be taking a flawed approach to the whole scenario. I am hoping this context allows someone to call me out on it if that's the case.
UPDATE 1
ALTER TABLE notifications ADD CONSTRAINT fk_rails_f395ae520f FOREIGN KEY index_notifications_on_item_id(item_id) REFERENCES items(id) ON DELETE CASCADE;
outputs:
CONSTRAINT `fk_rails_f395ae520f` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`) ON DELETE CASCADE,
Which is what I want, but I am still working on the KEY section.
UPDATE 2
ALTER TABLE notifications add COLUMN item_id INT(11) DEFAULT NULL;
ALTER TABLE notifications DROP INDEX index_notifications_on_user_id_and_notified_user_id, ADD UNIQUE KEY `item_id_and_user_id_stand_id_notified_user_id_unique_index` (stand_id, user_id, notified_user_id, item_id);
CREATE INDEX index_notifications_on_item_id ON notifications (item_id);
ALTER TABLE notifications ADD CONSTRAINT fk_rails_f395ae520f FOREIGN KEY index_notifications_on_item_id(item_id) REFERENCES items(id) ON DELETE CASCADE;
I believe these four lines in sequence answers the question of how to manually handle what my rails migration does. But, I am going to leave this question here. The question that remains is: "is it a terrible idea to do what I just did? and if so, how to do proceed?"
I have a website which has a users table and a movies table. I am creating a favourites table so that users can save movies to their favourites list. The question is concerning the favourites table which I have been adviced to use the below :
CREATE TABLE Favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
I noticed when reading about foreign keys there is an 'ON DELETE' and 'ON UPDATE' option where you can set to restrict, cascade etc...
If a user has favourited many movies, and then one of the movies is deleted from the movie table, what would happen if it the foreign key was set to "CASCADE"? would any rows from the favourites table be deleted also? What would happen if the foreign key was set to "RESTRICT"?
I am just after a basic explanation as I do not currently fully understand this.
13.1.17.3 Using FOREIGN KEY Constraints
...
CASCADE: Delete or update the row from the parent table, and automatically delete or update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported. Between two tables, do not define several ON UPDATE CASCADE clauses that act on the same column in the parent table or in the child table.
Note
Currently, cascaded foreign key actions do not activate triggers.
...
RESTRICT: Rejects the delete or update operation for the parent table. Specifying RESTRICT (or NO ACTION) is the same as omitting the ON DELETE or ON UPDATE clause.
NO ACTION: A keyword from standard SQL. In MySQL, equivalent to RESTRICT. The MySQL Server rejects the delete or update operation for
the parent table if there is a related foreign key value in the
referenced table. Some database systems have deferred checks, and NO
ACTION is a deferred check. In MySQL, foreign key constraints are
checked immediately, so NO ACTION is the same as RESTRICT.
...