views:

69

answers:

4

Sometimes we load data from a lot of sources, like files, streams, etc. Well ... to do it with low headaches, we usually disable foreign keys checking, the problem is that when we do get some foreign key constraint violations that we are not warned of that. How can we check this after restoring foreign key constraints?

A: 

Enabling the foreign key constraint will check all relations, so if there is something wrong, you will get an error.

Aaron Digulla
the question has the given that foreign key constraints are disabled for a reason. and turning them back on after the data is loaded won't cause mysql to check the existing data. so how is this answer useful?
longneck
Please prove that enabling the foreign keys doesn't fail in MySQL if there are violations. If that was true, foreign keys would be useless. If there is a bug, use ALTER TABLE to remove the FK constraints and then add them: When you add a FK constraint, the DB *must* check the data.
Aaron Digulla
mysql supports foreign keys and does enforce them. but it also allows you to temporarily disable enforcement of those keys to speed up data imports of relational data. see http://dev.mysql.com/doc/refman/5.0/en/server-session-variables.html#sysvar_foreign_key_checks
longneck
A: 

there is no built-in way to do this. the only thing i can think of would be to look at the TABLE_CONSTRAINTS and KEY_COLUMN_USAGE tables in the INFORMATION_SCHEMA database to manually check for rows that don't match.

longneck
A: 

"Turning on" the FK after the load should indeed do the check already.

If your DBMS doesn't do that, dump it.

If your DBMS doesn't do that and you still want to keep working with such crap, you could do a query of the appropriate SEMIMINUS expression of the RA.

This is likely to look something like :

SELECT ... FROM table_with_FK WHERE NOT EXISTS ( SELECT ... FROM table_with_PK WHERE PK_attribute1 = FK_attribute1 and PK_attribute2 = FK_attribute2 and ... ) AND <anything here that allows you to identify the loaded rows>

or a bit more modern (if your DBMS supports EXCEPT) :

SELECT FK_attributes FROM table_with_FK WHERE <anything here that allows you to identify the loaded rows> EXCEPT SELECT PK_attributes_possibly_renamed FROM table_with_PK ;

EDIT (answering to "not everyone needs oracle and IBM sized products. "dump it" is not good advice.")

The OP has very clearly indicated that he is DEFINITELY interested in data integrity. So he really should be using a DBMS product that DOES offer a bit of professional-level support for ensuring data integrity. I sincerely hope that "Oracle and IBM sized products" are NOT the only ones who do that.

Erwin Smout
not everyone needs oracle and IBM sized products. "dump it" is not good advice.
longneck
@longneck: There are more DBMS products than Oracle and IBM. In fact, given that the user is already using MySQL, I would think PostgreSQL would be the next logical choice if he did dump MySQL.
R. Bemrose
+1  A: 

It sounds like you could basically reword your question as "How can I ensure referential integrity with foreign keys disabled?"

I imagine the very "headaches" that made you disable the foreign keys are very thing they were intended to enforce. So the simplest answer to me seems to not disable them in the first place. Do it right the first time and you won't have to do it again later.

eaolson