I feel like I'm being stupid, but I can't find anywhere on the phpMyAdmin interface to add constraints to foreign keys e.g. CASCADE ON DELETE
I've looked for similar questions on here and on the phpMyAdmin wiki but I can't find anything about it.
I realise I could do this via the query interface, but I'd like to know how to do it through the graphical interface.
First, you should have your storage engine as InnoDB. Then select a table and go to 'Structure' tab.
Under the table you will see 'Relation view', click it. From there you could add constraints.
CASCADE
Whenever rows in the master (referenced) table are deleted (resp. updated), the respective rows of the child (referencing) table with a matching foreign key column will get deleted (resp. updated) as well. This is called a cascade delete (resp. update[2]).
RESTRICT
A value cannot be updated or deleted when a row exists in a foreign key table that references the value in the referenced table. Similarly, a row cannot be deleted as long as there is a reference to it from a foreign key table.
NO ACTION
NO ACTION and RESTRICT are very much alike. The main difference between NO ACTION and RESTRICT is that with NO ACTION the referential integrity check is done after trying to alter the table. RESTRICT does the check before trying to execute the UPDATE or DELETE statement. Both referential actions act the same if the referential integrity check fails: the UPDATE or DELETE statement will result in an error.
SET NULL
The foreign key values in the referencing row are set to NULL when the referenced row is updated or deleted. This is only possible if the respective columns in the referencing table are nullable. Due to the semantics of NULL, a referencing row with NULLs in the foreign key columns does not require a referenced row.
Firstly, you should choose storage engine as InnoDB.
Follow this way: click database_name -> More -> Designer
Related
I have a SQL table called "user" and a table "login" that has a foreign key constraint to a user. I want to be able to delete a row in the user table, even if there are login rows that reference it. Right now the database stops me from doing this.
Does anyone know how I can alter the table (through SQL or preferably through PHPmyAdmin to allow me to do this?
The tables were created automatically through Django.
Edit: To clarify: I don't want to cascade the delete. That is, I want the rows in the Login table to remain even though the user they reference is gone.
If you want this kind of behavior you have to create the foreign key with an ON DELETE CASCADE clause. With an ON DELETE CASCADE foreign key all rows referencing the user will be deleted with the user.
See: http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
Edit: If you want to keep the user_id in your login tables you just have to drop the foreign key. Anyway, If you are asking this is because you should probably do a logical delete instead of a physical delete: Physical vs. logical / soft delete of database record?
Proper way to do this is to mark offending users as "inactive" so they can't login and you still maintain referential integrity of your database.
Deleting data from master table that has referential integrity links to some data in slave table is bad praxis.
What is the best constraint to use on a forum table where users leave comments?
Assuming some users will be deleted at a later stage. if i delete a user who has commented, what happens to the users entry in the table?
Hope someone can explain.
There are two parts to this question:
how best to implement this? You can "soft-delete" user rows. This has the advantages of:
not losing user information
allowing users to be un-deleted
maintaining referential integrity without losing data linked to users
Soft-deleting can be implemented by adding another column to the users table, with a dateDeleted column -- if it's Null, then the user isn't deleted. I believe SO uses such a mechanism for deleting posts.
what does restrict cascade no action do? The MySQL docs say
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. InnoDB 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.
In other words, if you use this, you won't be able delete rows if doing so would break referential integrity.
I typically develop in MS Access and occasionally connect to a MySQL back end. I have a MySQL back end that isn't cascading deletes as I'd expect when I delete records. I'm wondering if it's because of how I've set up the table relationships (foreign keys). I don't know enough about MySQL to know if I've done this right. In designer view I set up the relationships using the designer view in MySQL. For a composite primary key field (InterviewID, Coder ID) in tblInterviews I created two separate relations to tblSB for each of these two primary key fields (tblSB includes a 3rd field, SBid, as its composite PK). The designer view is a little different from Access in that you can't highlight more than one field at a time to set up relationships. I did find forums that discuss the syntax for setting up the relationship with the foreign key but I don't know if it's equivalent to what I did in designer. I suspect not because currently when I try to delete a specific record (unique InterviewID, CoderID combination) ALL interview records for the CoderID in the InterviewID, CoderID combination get deleted (and this cascades through to other child tables as well). I also am wondering if I need to set up my primary key in a way that I am not currently doing (e.g., setting it up as an index, also). Any help would be appreciated. Thanks in advance.
To see what you've created, look at the DDL. (SHOW CREATE TABLE)
To enforce foreign key constraints--including cascading deletes--you probably want to use the innodb engine. The myisam engine will accept DDL that declares foreign keys, but it won't enforce them.
MySQL will let a foreign key target a non-unique column. The MySQL docs say
Deviation from SQL standards: A FOREIGN KEY constraint that references
a non-UNIQUE key is not standard SQL. It is an InnoDB extension to
standard SQL.
They call it an extension to SQL. I call it a mistake.
It means you can declare tblSB.interviewID as a foreign key referencing tblInterviews.interviewID. A standard SQL dbms wouldn't allow that.
The 5.6 docs say
However, the system does not enforce a requirement that the referenced
columns be UNIQUE or be declared NOT NULL. The handling of foreign key
references to nonunique keys or keys that contain NULL values is not
well defined for operations such as UPDATE or DELETE CASCADE. You are
advised to use foreign keys that reference only UNIQUE and NOT NULL
keys.
To my way of thinking, they're saying, "It was a bad idea, but we don't know how to fix it. So it's up to you to avoid it. We could warn you when you try it, but we're not going to do that, either."
Based on your comments, I'd say this constraint is right . . .
CONSTRAINT tblInterviewRecordtblSB
FOREIGN KEY (InterviewID, CoderID)
REFERENCES tblinterviewrecord (InterviewID, CoderID)
ON DELETE CASCADE ON UPDATE CASCADE
but these two are not, and should be deleted.
CONSTRAINT tblSB_ibfk_1
FOREIGN KEY (InterviewID)
REFERENCES tblinterviewrecord (InterviewID)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT tblSB_ibfk_2
FOREIGN KEY (CoderID)
REFERENCES tblinterviewrecord (CoderID)
ON DELETE CASCADE ON UPDATE CASCADE
I want to prevent deleting from parent table when he has children in other tables that.
I make like this
ALTER TABLE constant_det_tb
ADD CONSTRAINT fk_idparent
FOREIGN KEY (idparent)
REFERENCES constant_tb(id) ON DELETE RESTRICT
When I delete from parent constant_tb table, it delete the rows even the table has reference to another tables and it has records reference to it.
Make sure you have InnoDB as storage engine for all affected tables.
Check this (if not already) : http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
ON DELETE RESTRICT
reference option is all you need to achieve this.
Checking of foreign keys could be disabled for current session.
It can be enabled with
SET FOREIGN_KEY_CHECKS = 1;
I have been trying to learn from reading tutorials online and stuff but I just can't put my finger on it.
I have 2 tables at the moment (i'll have a lot more later on as I build my application) so I want to knock out this issue before expanding and coding.
I have my tables set to use InnoDB and I have each table related to each other by using user_id as foreign keys.
If i issue a DELETE query on the main users table, how can i get all records from other tables that are linked to the user_id field get deleted as well?
I know its simple, but I think I just need to ask the question myself so I can understand the answer rather than reading the answer... heh
thank a lot for any help.
Since they are InnoDB tables with proper FK relationships, you can simply use ON DELETE CASCADE in the foreign key definition. For example in one of the related tables:
FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE
However, this requires altering your existing schema to modify the foreign keys.
See the MySQL FOREIGN KEY docs for complete information.
You can cascade the DELETE using a DELETE trigger or using the technique Michael suggested, or you can manually write enough DELETE statements (deleting the entities from the bottom of the hierarchy upwards so you don't violate the foreign key constraints) though the latter is clearly not an ideal solution in terms of maintenance.
You may wish to use the TRIGGER approach if you want to fine tune the delete process (e.g. in case you don't want to destroy certain data related to the foreign key, or if you wanted to move it elsewhere or associate it to a different ID).
this is mysql example
ALTER TABLE table_with_foregin_key ADD FOREIGN KEY ( foreign_key_column )
REFERENCES table_name (
user_id
) ON DELETE CASCADE ON UPDATE CASCADE;