MySQL Updating/adding foreign key constraints - mysql

I have to update foreign constraints in a lot of tables in a lot of databases. The databases should(!) have the same structure, but I realized that there are sometimes little differences (e.g. constraints are different).
So my idea is, to "normalize" all tables by dropping foreign key constraints first.
Is there a way to drop all foreign key constraints referenced to a specified table/column from all tables?
For example:
DROP FOREIGN KEY FROM ... WHERE referenceTable = 'myTable'
AND referenceCol' = 'myId'

I think you need to look here:
http://dev.mysql.com/doc/refman/5.6/en/innodb-information-schema-system-tables.html
It is feasible. Youc could certainly do a single query to drop the keys you need to remove.

Related

Why do MySQL foreign key constraint names have to be unique?

I've noticed that I can't create two different foreign key constraints that have the same name, regardless of the set of tables in the schema that they're affecting.
Which I can cope with that, I couldn't find in the MySQL documentation where it says this is the case, nor why its the case. I'm using InnoDB, so maybe it's something specific to that, but I'm not finding that documented either.

Cascading delete removes unintended records

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

mysql drop foreign key without table copy

I have an InnoDB table claims which has about 240 million rows. The table has a foreign key constraint: CONSTRAINT FK78744BD7307102A9 FOREIGN KEY (ID) REFERENCES claim_details (ID). I want to delete the table claim_details as quickly as possible.
Based on some experimentation it seems that if I use SET foreign_key_checks = 0; drop claim_details and then re-enable foreign keys, mysql will continue to enforce the constraint even though the table no longer exists. So, I believe I must drop the constraint from the table.
I have tried to use ALTER TABLE claims DROP FOREIGN KEY FK78744BD7307102A9 to drop the constraint and the query has been in a state of "copy to tmp table" for over 24 hours (on a machine with no other load). I don't understand why dropping a constraint requires making a copy of the table. Is there any way to prevent this?
mysql version 5.1.48.
Starting with MySQL 5.6, MySQL supports dropping of foreign keys in-place/without copying. Oracle calls this Online DDL.
This table lists all Online DDL operations and their runtime behavior.
From my experience, dropping foreign keys and the corresponding constraints on a 600GB table is almost instantaneous. With 5.5 it would probably have taken days.
The only disadvantage that I am aware of is, that 5.6 does not allow you to reclaim table space. I.e. if you are using innodb_file_per_table, that file will not shrink when you drop indices. Only the unused data in the file will grow. You can easily check using SHOW TABLE STATUS, and the Data_free column.
I think there is no a good way to drop that foreign key
http://dev.mysql.com/doc/refman/5.5/en/innodb-create-index-limitations.html
"MySQL 5.5 does not support efficient creation or dropping of FOREIGN KEY constraints. Therefore, if you use ALTER TABLE to add or remove a REFERENCES constraint, the child table is copied, rather than using Fast Index Creation." This probably refers also to older versions of mysql.
I think the best method will be to dump data from claims with mysqldump, recreate table without foreign key referencing to claim_details, disable key check with SET foreign_key_checks = 0; in case you have other foreign keys and import back data for claims. Just remember to make separate dumps for data and structure so you don't need to edit this huge file to remove foreign key from table creation syntax.

Should i specifying INDEXES on fields which are foreign keys?

I have a MySQL database with about 10 tables, and about 6 of them are linked to each other in some way or another. MY question is, should i be specifying INDEXES on the foreign keys?
Thanks
from the docs:
"InnoDB 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 is in contrast to some older versions, in which indexes had to be created explicitly or the creation of foreign key constraints would fail.) index_name, if given, is used as described previously. "
source: http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
Yes you should, if cardinality is high enough.
Well, just mentioned that it's MySQL-specific question. Seems so that you have an index created automatically when not present with MySQL.
Gryphius's answer is more adequate then.

Can FOREIGN KEY and CREATE VIEW be used together?

I would like to make a view, and in that view alter the tables to have foreign keys.
From the MySQL manual can I see, that foreign keys only work on InnoDB, but my database is MyISAM.
So my question is, is it possible to create a view, and then create foreign keys in that view?
http:// dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
You have got everything completely wrong.
First of all MySQL allows you to use different table engines in a single table, so for example one table could be a MyISAM table and the other table could be an InnoDB table, it all depends on your need. The statement my database is MyISAM is completely wrong.
Secondly if you need for key constraints then use InnoDB tables and specify the constraints in the table definitions. You cannot specify foreign key constraints in views. Foreign key constraints are defined either when creating table or when altering the table.
A view is something else. Views are stored queries that when invoked produce a result set. See http://dev.mysql.com/doc/refman/5.0/en/views.html.